All the .NET APIs I have build used ASP.NET 2.0, which is a little bit behind. We just always require version in the URL as in "v1/productByIdentity/1234" or "v2/productByIdentity/1234". This new stuff is way better, though honestly these APIs have yet to introduce a breaking change. (The video is very focused and easy to understand, so thank you!)
Nick, I'm a bit disappointed that I can only click on the Like button once! This is video covers a great amount of detail in a concise and well-presented way. Great Job!
Good video but I wouldn't recommend using query strings or request headers for the version. Keeping it in the route is the best way to go imo. Makes it very explicit and required. This ensures that the client know what they are using.
Great Video on the topic have been using this package for quite a while even figured out how to handle the swagger docs but this video gave me new insights into the other versioning methods available to me thanks for the info keep them coming
Nick, you promised a while a go you will share with us the way you adopt to handle core domain return types and error handling. some people use exceptions, others use the Either and the likes. When will you fulfill?
Great introduction Nick! One side note: Don't forget to decorate your Controller with [ApiController], i was scratching my head for a while trying to figure out why the controller didn't pick up the configuration :)
A little known feature is that you can also target the entire assembly with [assembly: ApiController]. This will make all controllers in the project API controllers. The reason this is required is be cause a controller is just a controller. Some people mix UI controllers and API controllers in the same project. ApiControllerAttribute provides a simple and clear way to disambiguate the two.
is it possible to make the url-variant (api/v2/products) optional, just as the querystring and header variant are also optional? Or is it compulsory to use the /v in the url once that is defined in the routing?
Unfortunately, that is not possible. It is no different than if you had "order/{id}/items". AssumeDefaultVersionWhenUnspecified, therefore, will not likely not do what you want. In order to make that work, you would need to use multiple route templates. For example: [Route("[controller]")] [Route("v{version:apiVersion}/[controller]")] Now the route without the API version route constraint will assume the default version.
Same, getting an exception when having a v1 and a v2 method with the same route: Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: Conflicting method/path combination
Great video, I knew about this library but never went to find more about it. What is your process to learn about new libraries, do you read official docs and test it?
I will usually scan Microsoft repos for the helper libraries that they make. They follow specific naming patterns and they are easy to find. Sometimes they are not documented though to it’s either reading blogs or playing around with them myself.
Great tutorial , is there a best practice to include the version from assembly version number dynamically? and not hardcoded Like if I increase the api version this is the default version , and only for deprecated mention the version it was referring to
I think you can get around it if you properly version the assembly but in my opinion since versioning is such a sensitive thing that can break consumers, I would want to have it fully controlled
Great video. Question: if I have 3+ different endpoints, and each have a different version (1.0, 2.0 and 3.0) - can I tell the options to take the "highest" version?
@@limroto So you can but changing the default version once an API is live is dangerous since you can break existing consumers that didn't expect the change. If it is properly communicated then yeah you can with the default version property
Excellent video you covered everything except configuration of swagger for versioning. For dotNet Core 6 I can't find this method AddVersionedApiExplorer in Asp.Versioning.Mvc.ApiExplorer to be able to configure swagger for versioning. Do you know how this is done?
Things changed in .NET 6. You want to be using the "Asp.Versioning.Mvc.ApiExplorer" package. That will include all the transitive dependencies you need. The configuration has changed a little: services.AddApiVersioning() // support Minimal APIs .AddMvc() // add MVC core (e.g. controllers) .AddApiExplorer(); // add API explorer extensions
I am adopting similar ways in my azure functions api, going to newer versions without braking anything. There however I just create a new route for V2 and and another for V1. V1 points to one without versioning, and when I am ready I can just switch it to makes the one without V2 in url route to the V2 (making it default).
@@nickchapsas this is on my todo list for later in the year, but what I’m guessing this looks like in practice (and what I assume you mean but supported in the gateway) is more explicitly calling out the versions in routes where needed. Don’t think I’ll be able to leverage it as streamlined on the gateway end. Is what it is, just wasn’t sure if I was missing something.
Obviously you could use a traffic manager to reroute requests based on header values or url routes to different versions or clusters but I don’t have the full picture of your system to know exactly what to recommend
So I intentionally left that outside to not inflate the video in case someone isn't using Swagger. I haven't found a way to make it auto update but I have found a way to make it simpler to update. I am still looking into the "best" way to do it and one I have it will make a followup video
Is there support for default handling of the route versioning option. So the client won't have to put version in the address for 1.0 but for 2.0 the address will be v2/controller...?
The short answer is - no. In the same way that "order/{id}/items" will not route without an "{id}". The only way you can make this this work is if you register the default route twice. For example: [Route("[controller]"]) [Route("v{version:apiVersion}/[controller]")] If AssumeDefaultVersionWhenUnspecified=true, then "/controller" can now be matched against DefaultApiVersion.
Hey! As Lorenzo said I'm using Jetbrains Rider, which is a lot faster than VS. https run locally natively. Rider gives you a promt to intall the certificate and it just works.
There isn't really a concept of "versionless"; however, you can have a version-neutral API. This means it accepts any implemented API, including none at all. You can use the [ApiVersionNeutral] attribute or .IsApiVersionNeutral() convention.
Api versioning is not ready for odata controllers, because this feature do not support same name of actions or function on all apis ... actually this feature is not ready to production....
Deprecated doesn't mean it's inactive. It's an indication that it will be removed and it would guide the user to seek documentaiton for the new v2 version and the cutoff or end of life of the currect deprecated version.
All the .NET APIs I have build used ASP.NET 2.0, which is a little bit behind. We just always require version in the URL as in "v1/productByIdentity/1234" or "v2/productByIdentity/1234". This new stuff is way better, though honestly these APIs have yet to introduce a breaking change. (The video is very focused and easy to understand, so thank you!)
Nick, I'm a bit disappointed that I can only click on the Like button once! This is video covers a great amount of detail in a concise and well-presented way. Great Job!
Very clear and compact demonstration of the main mechanisms. Exactly what I was looking for.
Instead of using typeof(Contoller).GetMethod(...) In the last part of the video, you can use an expression, so it is at least a bit cleaner
Good video but I wouldn't recommend using query strings or request headers for the version. Keeping it in the route is the best way to go imo. Makes it very explicit and required. This ensures that the client know what they are using.
Thanks for making API versioning crystal clear.
Last night I was thinking of reading some versioning methods over the weekend. Suddenly you entered from the bright room. This is a miracle :)
Hahaha, perfect timing! This video was long overdue.
Great Video on the topic have been using this package for quite a while even figured out how to handle the swagger docs but this video gave me new insights into the other versioning methods available to me thanks for the info keep them coming
What was the trick for resolving the Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: Conflicting method/path combination error?
Nick, you promised a while a go you will share with us the way you adopt to handle core domain return types and error handling. some people use exceptions, others use the Either and the likes. When will you fulfill?
Great video and overview.
Would have been great if you put the link to the package in the video description though.
Thank you! I've been wondering how to version my mvc api. Now I know and it is nice that Microsoft has already done it for me. :)
Great and short video, covering all major usecases
Wonderful!!! Great job presenting. Quick and concise
This is sweet, small and crisp. Thanks 😊
Fantastic work on this video, Nick! Very informative, and very well put together!
Great introduction Nick! One side note: Don't forget to decorate your Controller with [ApiController], i was scratching my head for a while trying to figure out why the controller didn't pick up the configuration :)
A little known feature is that you can also target the entire assembly with [assembly: ApiController]. This will make all controllers in the project API controllers.
The reason this is required is be cause a controller is just a controller. Some people mix UI controllers and API controllers in the same project. ApiControllerAttribute provides a simple and clear way to disambiguate the two.
The v1 and v2 folders seem like a much better idea mate 🤣
amazing video. I will absolutely be putting this to use
Awesome, very helpful nice way to maintain API version
Wonderful video Nick, can't wait to use these methods to implement versioning in my own work. Thanks!
Thank you Nick, very good explanation!
is it possible to make the url-variant (api/v2/products) optional, just as the querystring and header variant are also optional? Or is it compulsory to use the /v in the url once that is defined in the routing?
Unfortunately, that is not possible. It is no different than if you had "order/{id}/items". AssumeDefaultVersionWhenUnspecified, therefore, will not likely not do what you want. In order to make that work, you would need to use multiple route templates. For example:
[Route("[controller]")]
[Route("v{version:apiVersion}/[controller]")]
Now the route without the API version route constraint will assume the default version.
Thank you for coming with crystal clear explanation.
Great video! Just what I've been looking for :)
Great Video! What about with Azure Functions and versioning?
Really useful library. Great job!
As usual, an informational video and thanks for sharing it. Any specific settings for Swagger UI to start showing version info?
exactly i am facing an exception when using swagger UI> any comments @nick chapsas?
Same, getting an exception when having a v1 and a v2 method with the same route:
Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: Conflicting method/path combination
Great content as always man! Helped me a lot. thanks!
Wow this is really impressive I'm going to test this out. Thanks 👍👍
Excellent video. Thank you sir.
Just in time! thanks for sharing
Great video, I knew about this library but never went to find more about it. What is your process to learn about new libraries, do you read official docs and test it?
I will usually scan Microsoft repos for the helper libraries that they make. They follow specific naming patterns and they are easy to find. Sometimes they are not documented though to it’s either reading blogs or playing around with them myself.
Excellent video. Thanks for this.
Really nice introduction tutorial.
Just wondering if you have a complete net core API tutorial series... would be interested in that.
thanks for this, btw.
I actually do but it's for REST APIs
Really Awesome Video! Thanks for sharing!
I booked marked this video!
Your all videos are so informative and well prepared. Finally you look like titanic actor :)
Great video again, Nick.
Insightful, great understands
very well explained. thanks
Thank you @Nick
Great tutorial , is there a best practice to include the version from assembly version number dynamically? and not hardcoded
Like if I increase the api version this is the default version , and only for deprecated mention the version it was referring to
I think you can get around it if you properly version the assembly but in my opinion since versioning is such a sensitive thing that can break consumers, I would want to have it fully controlled
Great, and timely video, Nick! Thank you. Btw “2 dots” = ‘colon’ :)
I think I was born with the defect to mix colon and semicolon and also mix square brackets with curly braces 😂
@@nickchapsas curly brackets are totally fine as well
Great video, thanks!
Thank you for very usefull tip! As always.
Awesome video, subscribed! And saved it to a playlist so I can come back to it in the future when dealing with different versions :)
this was great!! thanks!!!
Thanks for the video ! Love it !
thanks once again! great content
Thanks for sharing this information
Great video. I wish I had a project where it would be used, sigh :(
Sick vid bro
This is why i follow you....
Great video.
Question: if I have 3+ different endpoints, and each have a different version (1.0, 2.0 and 3.0) - can I tell the options to take the "highest" version?
Do you mean as the default version?
@@nickchapsas Yes.
@@limroto So you can but changing the default version once an API is live is dangerous since you can break existing consumers that didn't expect the change. If it is properly communicated then yeah you can with the default version property
Great video!
Could you show how to combine swagger and versioning
Great informative video. Thank you!
Great content❤
Very useful!
Can you also make a video on how to add swagger api definitions for different versions? Swagger UI stopped working after I added API versioning.
That's a good one 👍
Excellent video you covered everything except configuration of swagger for versioning. For dotNet Core 6 I can't find this method AddVersionedApiExplorer in Asp.Versioning.Mvc.ApiExplorer to be able to configure swagger for versioning. Do you know how this is done?
Things changed in .NET 6. You want to be using the "Asp.Versioning.Mvc.ApiExplorer" package. That will include all the transitive dependencies you need. The configuration has changed a little:
services.AddApiVersioning() // support Minimal APIs
.AddMvc() // add MVC core (e.g. controllers)
.AddApiExplorer(); // add API explorer extensions
well explained!
Really good Tutorial ob this topic!
What shortcut did you press at 3:45 for the "options" be autocompleted?
That would be Ctrl + Space in my Rider config
Thank You
I am adopting similar ways in my azure functions api, going to newer versions without braking anything. There however I just create a new route for V2 and and another for V1. V1 points to one without versioning, and when I am ready I can just switch it to makes the one without V2 in url route to the V2 (making it default).
amazing
Gràcies!
Great video
Good job!
what if want use "api/v2.1/product" than what changes has to be made
do you have some nice distributed lock examples?
Could you please refer me to a video where you use multiple controllers like you showed at the start(v1 and v2 folders)?
nice intro! any thoughts on integrating api versioning when you have a gateway in ocelot, envoy, AAG, aws gateway, etc.?
As long as your versioning strategy is supported by the gateway I can't see how it would be an issue
@@nickchapsas this is on my todo list for later in the year, but what I’m guessing this looks like in practice (and what I assume you mean but supported in the gateway) is more explicitly calling out the versions in routes where needed. Don’t think I’ll be able to leverage it as streamlined on the gateway end. Is what it is, just wasn’t sure if I was missing something.
Obviously you could use a traffic manager to reroute requests based on header values or url routes to different versions or clusters but I don’t have the full picture of your system to know exactly what to recommend
does build in swagger in .net 5 auto-update with it?
So I intentionally left that outside to not inflate the video in case someone isn't using Swagger. I haven't found a way to make it auto update but I have found a way to make it simpler to update. I am still looking into the "best" way to do it and one I have it will make a followup video
@@nickchapsas thank you can't wait for your new videos :)
@@nickchapsas Swashbuckle can do this all for you. Just need to setup the swagger gen options.
@@IssaFram do you know how to configure the options to autoupdate the versions ?
Awesome.
Contracts? The way you mention them makes me think you've talked about it before - which video?
In One project how we cosume wcf and web api both. can you help with web.config how we write for it
What IDE are yyou using?
Thanks!!
Is there support for default handling of the route versioning option. So the client won't have to put version in the address for 1.0 but for 2.0 the address will be v2/controller...?
The short answer is - no. In the same way that "order/{id}/items" will not route without an "{id}". The only way you can make this this work is if you register the default route twice. For example:
[Route("[controller]"])
[Route("v{version:apiVersion}/[controller]")]
If AssumeDefaultVersionWhenUnspecified=true, then "/controller" can now be matched against DefaultApiVersion.
What ide are you using? it ran so fast when you hit run!
Also side note perchance how did you get https running locally?
I think it is this one www.jetbrains.com/rider/
Hey! As Lorenzo said I'm using Jetbrains Rider, which is a lot faster than VS. https run locally natively. Rider gives you a promt to intall the certificate and it just works.
How to handle versionless calls to default version for url routing versioning
There isn't really a concept of "versionless"; however, you can have a version-neutral API. This means it accepts any implemented API, including none at all. You can use the [ApiVersionNeutral] attribute or .IsApiVersionNeutral() convention.
All your videos, text are not visible in visual studio. can you somehow zoom into the screen while recroding? like how @IAmTimCorey does.
Watch the video on fullscreen. Any bigger and it would be impossible for me to actually write the code that I'm showing
Api versioning is not ready for odata controllers, because this feature do not support same name of actions or function on all apis ... actually this feature is not ready to production....
How come that you have v1 deprecated but you still have an access to it?
Deprecated doesn't mean it's inactive. It's an indication that it will be removed and it would guide the user to seek documentaiton for the new v2 version and the cutoff or end of life of the currect deprecated version.
@@nickchapsas got it! Thanks for the explanation.
Copy of method is not solution for frequently releases for minor changes or Update.
Changing the route is a breaking change :(
How is that "Elegant" when you need to duplicate all your code (repositories models etc..)
You don't. You can handle all that in the mapping layer.
Й
Ф
Ф