AspNetCoreOData icon indicating copy to clipboard operation
AspNetCoreOData copied to clipboard

Docs Request: Setup OData 8 with Swagger/OpenAPI

Open Tiberriver256 opened this issue 2 years ago • 7 comments

I see some sample code in here but would we be able to get a doc on how to setup OpenAPI with OData 8?

Tiberriver256 avatar Oct 13 '21 19:10 Tiberriver256

@Tiberriver256 can you add the link to "here"?

xuzhg avatar Oct 15 '21 19:10 xuzhg

Yeah sorry for the ambiguity. I just meant the samples folder in this repo. It's somewhat useful but kind of hard to suss out the exact steps that would be needed to get Swagger working w/ the parameters (i.e. $filter/$top/etc.) actually showing up in the swagger json file.

Tiberriver256 avatar Oct 15 '21 19:10 Tiberriver256

@Tiberriver256 I made few packages for work with OData 8 and one of features is support Swagger it's in a beta stage, but you can find code for support $filter/$top/etc. that I extracted from support for OData 7.+

Other feature is generation of swagger.json during the build

vfofanov avatar Oct 16 '21 11:10 vfofanov

Thanks @vfofanov! Interesting approach doing it during the build step. I took a slightly different approach in my experiment here. It uses another library to convert the edm model directly to swagger. Love some feedback on it!

Tiberriver256 avatar Nov 05 '21 23:11 Tiberriver256

Hi guys, in the end, what is the current recommended and most supported way of exposing OData endpoints via OpenAPI? Because I am puzzled with the lack of clear information and the options out there that none work properly. You look at courses that instruct you to use the ODataController but then even in some sample with Swagger here, that is not used. I managed to have something working on latest .NET 6 and packages with [ApiController] on top of ODataController but of course the OData query params are not there. I'm also bothered by the fact that I want to somehow properly spec the response of those endpoints where for collections for example you have an OData object with a Values property containing the actual response. How to do that best?

jazzmanro avatar Dec 04 '21 18:12 jazzmanro

There have been many issues and discussions over the years. Admittedly, I was :trollface:ing through the issues and this seemed to be the most relevant. I was tempted to open a new issue, but I think this is the right place to start.

First, I want to call out that what OData should be doing IMHO is officially supporting the API Explorer. Everything else is secondary. By simply supporting the API Explorer properly, other things and consumers such as OpenAPI generators just work. The 2 most popular OpenAPI generators - Swashbuckle and NSwag - work this way. Reach and usability extend beyond OpenAPI though. Testing and test automation are a few others.

The changes in OData 8.0 configure the route attribute information which is why anything works at all today. Kudos to @xuzhg and team for this advancement. However, there is still a lot of stuff missing. There are lots of ways it could be provided, but these are first-class concepts that should be supported and owned by OData.

I'll point out that using the EDM for this purpose - alone - will not solve this problem. There is a lot of information that the API Explorer should and can expose that is not in the EDM. The most obvious is OData query options, but there's more. Some pieces of information are defined in code. Some of the information is also based on the protocol itself, which is why it should be owned by the OData team. Community support is welcome and appreciated, but IMO they shouldn't be expected to know the protocol itself. There can be a big ramp up period. I'm not sure I could have brought OData support to API Versioning without deep knowledge of the protocol and code stretching back to the Astoria days.

Here are a few more advanced, undocumented scenarios:

Return an Entity Set Collections need to be returned in the form { values = [] } which is currently undetectable.

Adding a Navigation Link Requires PUT or POST with { @odata.id = "<URL>" }. The {navigationProperty} template parameter can be substituted and fanned out for each property available in the EDM.

Deleting a Navigation Link Requires DELETE with $id query parameter for the related key. In OData 4.01 now requires the relate key be in the URL.

Action Parameters The code implementation is just a Dictionary<string, object>, which provides no type or member information. This is a case where the EDM can be useful though. A non-executable substitute type can be generated from the EDM and used as a stand-in because most API Explorer consumers work off of Reflection against the ApiDescription.ModelMetadata.

... and the list goes on.

I see @vfofanov lifted out the support from API Versioning, which isn't too surprising. It was meant to be generic, but the implementation only intended for API Versioning; at least, until OData formally supports it. Things have gotten simpler, but if you're curious, you can find the latest, OData 8.0 supported implementation here.

That's my 2¢. If there is real interest and commitment to seeing this come to fruition, I'm willing to help out. I'm not sure if that's @xuzhg call or some other PM. I won't start any work or PRs though without a commitment of the feature[s], design, schedule, etc. An initial PR would mostly be a lift and shift from API Versioning. Given the impact to other areas of the ecosystem and community, an official release should target no later than .NET 7.0 (11/2022).

cc: @mikepizzo

commonsensesoftware avatar Mar 20 '22 00:03 commonsensesoftware

I'll add to the comment from @commonsensesoftware that although OData query options are not included in the Edm generated from the ConventionModelBuilder today they can be included in the Edm using the Org.OData.Capabilities.V1 vocabulary extension.

SAP has for some time generated enough data in their edmx to generate accurate OpenAPI as it's a pretty core component to the way they create drag and drop web user interfaces and also how their API Gateway product works. It's been a while since I worked with one of their APIs, but I believe they are using the Capabilities vocabulary if I remember right.

Working towards getting that data into the edm model would mean 1) that tools like odata-openapi and OpenAPI.NET.OData would generate better OpenAPI from .Net Core OData APIs and 2) I think it would also mean a general improved experience for developers more familiar with consumption of the Edmx than OpenAPI.

Tiberriver256 avatar Mar 20 '22 00:03 Tiberriver256