Closed Gigabyte0x1337 closed 2 years ago
Short answer - no.
OData 8 is another massive overhaul of OData. I considered it, but things are quite different. Furthermore, the unofficial release date for OData likely won't come before the first of the year.
A number of people will not adopt pre-release versions for production work. It would seem it's better to release and prepare for OData 8. It's currently very rough. I've had some discussions with the team so I hope there will be a good pairing by release. There will likely be a pre-release version, but I don't know when yet.
Hello
The RC2 is out here: https://github.com/OData/AspNetCoreOData/releases/tag/8.0.0-rc2
Any news?
Even RC3. Do you have any estimations about preview-version?
Not to ignore the thread, but as I've said many times in the past, I don't chase pre-releases. This is especially true in ranking the priority of issues against official releases. There's no team or funding here. I'm a one-man show. I've burned down more that 50% of the open issues (tracking offline), so there's a reasonable chance I'll be able to start this work up again in the near future.
I've done my best to collaborate with the OData team, but it never seems to amount to more than discussion. 8.0
will effectively be a rewrite - again. I did learn some good lessons in 7.x
with Endpoint Routing that I think will carry over. It's been quite a few months since I've got to look at how things have changed; we'll see.
I made it clear to the OData lead dev that API versioning needs a hook or mechanism to select an appropriate EDM. All of the OData implementations expect there to be exactly just one EDM. The suggestion from the OData team was to design things such that you only need single EDM. They essentially implied that things could be made to work though extensions and/or annotations. On some level that might be true. I've been down that road for years and already know that it leads nowhere. EDM-to-Version is the only sensible way to configure things. There's a myriad of reasons, but fundamentally it's around all the existing tooling and behaviors. One giant EDM would be a nightmare to look at and would break all known external functionality. For example, requesting ~/$metadata?api-version=2.0
should work with existing tooling and so on just as if versioning wasn't applied.
In the 7.x
timeframe, I managed to figure out a way to get in front of resolving the current IEdmModel
for the current request from the underlying container. The initial 8.0
implementation solved a whole class of other existing problems, but made addressing that very difficult. You can see where this was going in the public OData branch here. This will be one of the first issues to sort out resuming the work. This is what lead to my callout for the need of aforementioned hook. I never heard anything back with respect to the evolving design so I doubt it happened.
I took the liberty of scanning the latest code. Sadly, doesn't look like much changed. To see a sense of what I mean, check out ODataOptions.Models. The fact that this property still publicly exposes unnamed tuples is - how shall I say tactfully - not so good design. Code analysis would flag this immediately if enabled. It was fine in the early previews, but not for RC or release. Regardless, this design leads to a problem by which the IEdmModel
is no longer retrieved from IServiceProvider
as it has been in all previous versions since DI was introduced. You can see the pain this causes for API Versioning here. The other thing I didn't like about it is that you have to use a special variant of .AddModels
inside .EnableApiVersioning
. You can see a preview sample of the setup here. In fairness, that's probably not all that different than MapODataServiceRoute
versus MapVersionedODataRoute
, which I also didn't like. A key difference here is the place where you do the registration. At least in the old model, Intellisense might help you with the methods side-by-side. Maybe I'll be able to improve this once I dive back in.
In any event, that should give you a little taste of challenges I'll be facing. It's also not just the work itself, but relearning the OData codebase, which has consistently been required to make versioning work. I've been a strong advocate of the OData protocol from the beginning, but the moving target that is the official implementation has made me want to throw it over the fence and wash my hands of it more than once.
In terms of estimate or timeline, I honestly don't have one. I can tell you that of the remaining other open investigations or bugs, I'm down to OData-related issues. There is a high probability that most of those issues are applicable in 8.0
. This means that while I might not be focused on getting an 8.0
release out - preview or otherwise, I'll be working toward that goal indirectly.
Thank you for the comprehensive answer! I see the problem and wish you luck with the issues you work on. Hopefully we will see one day the versioning for the OData 8. It is out already. I strongly agree about EDM-to-Version. Hope the guys from OData will understand it as well
Dear @commonsensesoftware, We are actively working on our API and trying different version combinations of OData/Swagger/ApiVersioning and checking everything around. I am not sure, if you aware of this work from OData team: https://devblogs.microsoft.com/odata/api-versioning-extension-with-asp-net-core-odata-8/ It seems that they already did part, which you only plan to do...
@jfshark Interesting. I hadn't seen this particular post yet. That example project is a fairly high-level and misses a lot of more fundamental parts, but it's a good start. It does highlight some of the mechanics to make things work, which should be useful to lighting up support. It's seems Sam saw the wisdom of needing one EDM per API version. I don't troll the OData issues much, but I would guess that the post was reaction to feedback or questions on their repo. I haven't had any conversations with the OData team since last November or December.
The reality is that OData is a team and delivering the framework is a full-time job that they get paid for. I'm passionate about services and all things REST. I really do love helping out the community and shepherding this project. Unfortunately, I'm a one-man show and I don't get anything else out of it besides the community's appreciation and the proverbial "pat on the back". The laws of physics would enable me to spend more time on the project, I would. Quality is of the upmost importance to me and I'm not going to ship garbage that I know is broken or incomplete. While the current objective is to stabilize targeting OData 7.x, much of that work will carry over to OData 8.0. So in a roundabout way, 8.0 work is happening, albeit slower than one would like.
Thank you for sharing this post though. Since it has source code, it should be useful.
π£ Extra! Extra! Read all about! π°
You've all been waiting a long time, but the release is nigh. As expected, supporting OData 8.0 was a complete rewrite. I applaud the OData team for properly supporting Endpoint Routing by computing the OData route templates upfront ππ½. Their solution was different, but fundamentally used the same concepts API Versioning was using. I'm certainly happy to ditch all that code because I never wanted to own it.
Despite asking for it, no hook or extension point was ever provided that would enable an EDM per API version design. The example @jfshark linked to does show something working, but it's very prescriptive and highlights the need for multiple EDMs per prefix. Restricting the options to only a prefix is infeasible; especially, since versioning by URL is not RESTful. A number of the internal
OData types weren't doing me any favors either. If that weren't enough, the OData 8.0 libraries support OData 4.01 which has protocol-level changes that few probably have realized. Those changes certainly have effects on the API Explorer.
In spite of these challenges, I've finally been able to create a workable solution. In its simplest form, the configuration is simply:
services.AddControllers().AddOData();
services.AddApiVersioning().AddOData();
This might not look like enough, but it is. Remember that API Versioning provides IModelConfiguration
to configure an EDM for each API version. As long as there are 1+ API versions, an EDM can be created for each version without a prefix and, hence, no additional configuration. If you do want a prefix, it's as simple as:
services.AddControllers().AddOData();
services.AddApiVersioning().AddOData( options => options.AddRouteComponents( "api" ) );
Notice that you configure the API Versioning options and not the default ODataOptions
. This is how the two pieces are separated. ODataOptions
can be used to configure everything except RouteComponents
. Think of them as a template. If you do attempt to configure ODataOptions.RouteComponents
or ODataOptions.AddRouteComponents
, they are simply ignored. Similarly, ODataApiVersioningOptions.AddRoutComponents
does not directly expose or accept an IEdmModel
, but it does have parity with all of the other OData configuration options. If you prefer not to use IModelConfiguration
, the VersionedODataModelBuilder
will now be exposed via ODataApiVersioningOptions.ModelBuilder
. For example, you could have:
services.AddApiVersioning()
.AddOData( options =>
{
options.ModelBuilder.DefaultModelConfiguration = ( builder, apiVersion, prefix ) =>
{
// inline model configuration
};
} );
The other parts and design of VersionedODataModelBuilder
remain unchanged from previous versions.
Now, I know what you're thinking, "That's great, but I need OpenAPI support too." Let me answer your ππ½ππ½ππ½. The refactored implementation for the API Explorer now supports OData 8.0 too! In its simplest form, the configuration might look like:
services.AddControllers()
.AddOData( options =>
{
options.Count().OrderBy().Select();
// not strictly necessary, but pairs down lots of route forms that you
// are probably not interested in
options.RouteOptions.EnableKeyInParenthesis = false;
options.RouteOptions.EnableNonParenthesisForEmptyParameterFunction = true;
options.RouteOptions.EnableQualifiedOperationCall = false;
options.RouteOptions.EnableUnqualifiedOperationCall = true;
} );
services.AddApiVersioning()
.AddOData( options => options.AddRoutComponents( "api" ) );
.AddODataApiExplorer( options =>
{
options.GroupNameFormat = "'v'VVV";
// configure query options which cannot otherwise be configured by OData conventions
options.QueryOptions.Controller<V1.PeopleController>()
.Action( c => c.Get( default ) )
.AllowOrderBy( "firstName", "lastName" );
} );
At this point, you're probably overwhelmed with excitement πΉ and you're thinking, "Show me the code!". You need look no further than the all new and updated OData examples here.
The final, but millionπ°π°π° question is, "When can I get it?". Soon. π Be sure to follow the recent announcement as well as the 6.0 roadmap. This actually just the tip of the iceberg. There's many more great features queued up for the 6.0 release too. As soon as I'm able to sort out all the package publishing tasks, I plan to get a pre-release out straight away. If you just can't wait, the code is there for you to play with. I really hope some of you try it out. I'd love to hear feedback and any issue you might find; particularly in the OpenAPI area. The coverage is solid, but OData has a very big test matrix for features, which is difficult to facilitate with just one person.
Enjoy! I'm looking forward to getting this out to you all ASAP.
The wait is almost over. 6.0
Preview 1 is now available with support for OData 8.0 and .NET 6.0:
You should find it stable and with all of the OData bug fixes that have been stockpiling. The last major hurdle is ironing out code signing, which is just administrative stuff on my side. Please try it out and let me know if you run into any issues. If you're unsure how to navigate the changes, the example projects are the best place to start.
Thanks for your effort it's very appreciated. I will try it out when I find a moment. π
The wait is almost over.
6.0
Preview 1 is now available with support for OData 8.0 and .NET 6.0:You should find it stable and with all of the OData bug fixes that have been stockpiling. The last major hurdle is ironing out code signing, which is just administrative stuff on my side. Please try it out and let me know if you run into any issues. If you're unsure how to navigate the changes, the example projects are the best place to start.
It works for me, i even have custom attribute routing and it still works fine.
@Gigabyte0x1337 thank you for confirming.
Preview 3 is just around the corner. Some folks asked so if you still need .NET Core 3.1, it will be included as a target. I will point out that .NET Core 3.1 will be out of support 12/3/2022. If you are in that camp, expect that the 7.0 release will drop it. Since the 6.0 release contains so many fixes, I'd like to make sure you're in a reasonable and stable spot with OData 8.0 while you iron out your own transition story to 7.0.
The 6.0
release is fully signed and published. I don't think there is any more to add here. I've opened up a discussion for the release if there are more questions or comments.
If you're looking for 5.1
support, I'm still fighting with publishing and code signing; NuGet is rejecting it. It should not be affected by this issue because it will not support OData 8.0 anyway. For OData 8.x+ and .NET 6.0+ support, you'll need to update to 6.0
.
Thanks for the support, feedback, and patience.
Will support for odata 8 be included in the 5.0 release ?