Elegant API Versioning in ASP.NET Core (Web API)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody i'm nick and this video i'm going to show you how you can use microsoft's elegant api version in nougat package to add amazing api versioning of all sorts of types for your asp.net core api i'm going to cover most of the features not all of them because it is a quite a big package but pretty much every major use case that you might have should be covered in this video so without any further ado let's go straight into the code so what i have here is a simple api controller and it only has one endpoint the get product endpoint which all it does is it gets a good from the route here from the get http get attribute and then it's faking that it's getting a product just to keep the scope of the video narrow and just returns it as okay like it found it and this is a very common scenario like rest apis or crowd apis or any sort of apis and if i go to postman in fact if i run this first and i go to postman and i file a request to that you will see now that it's returning it great now let's say we're three years into the future or two years in the future and we need to make a breaking change on our api but we don't want to break any of our existing customers using they pay what we want to do instead is put a note out but this api will be potentially obsolete or deprecate in the future or not even do that for now just parallely support both api versions and then create a new major release let's say how would we do that well that's a very interesting question you can do that in multiple levels there's not one way to do this but one very simple way to do this is by first going into nuget and searching for the microsoft dot asp.net core dot uh i always forget that yeah.mvc.versioning so it's this package over here and all i need to do is add it into my project and close that nuget package window and that package basically has everything we need to start it off very simply the first thing you need to do is go into your startup.cs and update the configure services method to include the services. add api version call just by doing that you now have some sort of versioning however you haven't really told net core or asp.net core how you're versioning your api and what you're doing exactly which means that if you just run this without doing anything and you try to call an endpoint the exact same endpoint that was working before you now get an error which says that hey an api version is required but not specified that is because we haven't configured our api versioning to default to a specific version for us the first version presumably is v1 or v1.0 the default way that this works in dot net core is to have the api hyphen version query string parameter and say equals to 1.0 for example and that will default and work because or doesn't really default we just specify hey api version is one use the first one and this will work fine however this is not ideal because if you make that after the fact mandatory then your consumers will break what you want to do instead is you want to enable your api versioning to default to the first version how you can do that well it turns out that this parenthesis actually accepts an options object let me just stop running this project and what i'm going to do is i'm going to expand the parentheses and then this options object has a ton of properties we can change the first one would be the assume default version when unspecified and all you want to say here is uh true so we want it to assume the default version so if i was to run this again and now not have the api version in here it is running it is running and send the request as you can see now it is returning without me having to say v1 and that's because it will default to the default when unspecified but what if you want to have a different version for the default instead of just v 1.0 well you can say options dot default api version and here you can tell the system that your default api version is 1.1 if you had such a version which will translate to those are major and minor units so this will translate to 1.1 in our case usually the first one you're gonna version is 1.0 uh and in that scenario you don't even need to specify 1.0 here because api version has a default which is 1.0 so now not only we default to a version when specified but we also specify what the default is so great we have that covered but now we need to add the extra endpoint and there's many ways you can do this there's no one right or wrong way some people like i've shown in my previous videos will go under controllers and make a v1 and v2 uh subcontroller folders and then they will put the v1 controllers to the v1 folder and the v2 controls in the video folder we could very much do that and it's a fine practice um the only reason why i'm not going to do this is again because i'm keeping the scope of the video narrow but it's a great way to organize your controllers if you want to do that in my scenario i'm gonna showcase how you add a v2 of a specific action in the controller because that might sometimes happen you know the v2 api doesn't have to change everything about the v2 api but if you break at least one then it is a major api change and one of the ways you can do that is copy the same thing paste it here and you can say get product v1 and get product v2 that being said since the object changes itself you can do the same thing either with the namespace or the object's name and have a v1 and a v2 which means that we can rename this to v1 now and again this is completely up to you some people do it on the class some people do it on the namespace with a folder um you can do it the way you like it and what i'm going to do now in that v1 class is i'm going to create the v2 class and the breaking change for that response will be the name property we're going to name it product name now it's a pretty stupid breaking change if you want my opinion but it illustrates the point and now we have our breaking change obviously if i just hit that end point i'm gonna get an error saying hey i don't know where i should match this request because nothing tells me where it should go they look identical so how do we differentiate them well first what you can do is you can use the api version attribute and in the api version you can say this supports 1.0 and also supports 2.0 but only one of them is a 2.0 so for that scenario you can say actually let me not do it with comma let me do the extended version which is you can use the map to api version attribute and you can specify the version here which is 2.0 and now when i run this when i go back here when i don't use anything in the query string parameter or the header or anything and i run this works fine i'm getting the old contract you see it's product name but if i add coma api version equals 2.0 that's not equals that's equals then i'm getting the new version and of course you could do this in separate controllers and in fact it might be the recommended approach to do it but again for now we're keeping it in the same controller just to show you how that also plays out because you might just want to map one of the actions to the new version so that's one of the ways but you might be thinking hey what if i don't want to have it as a query string parameter that's weird good question viewer what you need to do is of course remove that from here and we can go to the startup.cs and again this is our magic space of api versioning you can just say options dot and you can use an api version reader and this is effectively a mechanism to tell the request this is where i'm gonna get my version from the default is the query string parameter but you might want to change that one very common practice for example is having it in the accept header or having it in the accept version header or the content type there's so many if you want to have it in the accept header all you need to do is say new media type api version reader and here you specify the parameter name which is for me version if i could type it here you go so now if i run this again and go back to postman and put back that api version in the query string parameter and i run it doesn't do anything it ignores it because i just overrode the query string default handling so what i'm going to do instead is i'm going to go to the headers and because writer already used an accept i'm going to copy that and paste it here and then i think by default application json is there when you're dealing with json requests so what you would have in that scenario is a semicolon and then version equals to 2.0 and if i do that sorry now you can see that i get the right contract because it's using that from the header you might be asking however what if i want to have my own api version header you might want to have something called x version for example which is totally fine it's completely up to you you're not having to conform to any standard you if you want to do that you can do it so for that you can use the new header api version reader and you can paste that here and if you do that and i run my code again then let me just copy that and you can simply obviously remove it from here we don't need it anymore you have x version as the header and then the value is 2.0 and if i press send as you can see still in 2.0 if i remove it or i make it 1.0 again back to the first one so that's how you can be flexible with where you want it but it doesn't stop it there in some scenarios you might want to support multiple ways of your application handling the vision because even the version handling way might be legacy you want to effectively deprecate in the future how can you do this well what you can do and let's actually use the previous examples that i just used if i just stop this what we have is the media type let me just put it in a new line and we also have the header type you can use the api version reader class and it has a combined method and this will combine multiple methods into one which allows you to use both of them effectively in your versioning to pick up your vision so for example you can have the x version here and you can also have the uh i think i did a mistake here i'll fix it in a second so you have the x version and you have the simple version from the accept header and if i remove that and i run my code and go back to the postman then x version here v1 x version here v2 or version equals 2.0 if i disable that still works i don't think i've tried to see exactly what happens when you have both and they're wrong okay it is being handled the application will understand that you're requesting both of them and it will throw so that's good i didn't actually test this before the video but this is how you can have multiple ones as well now if i go to the headers you will see if i run this request again you will see that nothing reports back what api versions are supported and this is usually good to know when somebody's integrating with you because they might want to try the new one they might want to see if there's a minor version that they can upgrade to and so on and so forth the way you can do this is again from the module method api versioning you can do options dot and you can use the report api versions equals true and if you do that then you can debug your code run the exact same request and you'll see in the response headers that we now have an api supported versions with 1.0 and 2.0 as versions that the api supports which is great because now we know exactly what's up the extra thing is what if v1 is actually deprecated and we want to kill it in the future and we communicated that to the customers and we want to also let the developers know through header or whoever is integrating with the api all you need to do is set the deprecated property in the api version to true and as long as you do that there will be a new header assuming i did this correctly as you can see now api deprecated versions 1.0 api support versions 2.0 so we're reporting back in address that's a good practice um so your consumers know um what version you they should be on potentially they're going to google hey what about the deprecation what's the date i need to start moving forward when is this end of life so it's good to communicate it back a final thing that you might want to have or support is url based versioning you know voiceless api force class it's how i used to do it in my uh rest api video so i would have a v1 here and then the v2 would have a v2 there and this is also a very good way to version your obligation it's there's absolutely nothing wrong with it it's just another way to do it the way you can configure it here is as follows first i'm going to comment out this api version reader because we just want to use the um the route one so what i need to do here is say force class v and then angle brackets brace it br whatever they're called and then version and then colon two dots api version and if i do that now i can run my application and if i go to postman again this will now be ignored uh in fact i should get a follow for when i click send and indeed i do because this url doesn't exist anymore the url is voiceless v and the version now the version comes in two ways you can either have the full major and minor version and you can just say 2.0 and you get the right version or 1.0 and you get the right version or you can just say if you want to only deal with major so if you don't have 1.1 or 1.2 you just care about major it will understand v1 and also v2 so it uses the major unit if there is no dot there very very flexible very very smart and i really really like that and it actually doesn't stop there because in fact let me just remove that because what if you don't wanna decorate your controller with all of these api version attributes in my opinion by the way i would leave them there because it makes it visible when you're looking at the controller but there's also a different way that's more of your cup of tea where you can go to the startup so let me just remove that and in the now i removed all the versioning and if i go to the startup and i enable back this api versioning strategy i didn't want to do this that that would that's what i want to do you can use options dot conventions and then you can have controller and you can get controller by type in my scenario it's the product controller so you have this fluent api and you can just say at the controller level has api version i'm gonna use the extension method on this which allows me to go forward yes this one and you simply say one comma zero and this version allows me to chain multiple ones so i can say also has api version 2 comma 0 and if 1.0 is deprecated why don't you like this oh because i said versions listen to me version if one is deprecated you can say has deprecated version 1.0 and has api versions 2.0 and on top of that you can say on a specific action level and this is a bit dirtier so i don't really recommend it but i'm going to show you how you can do it anyway you can say type of products controller dot get method and then you can do name of controller dot v2 get product v2 i'm going to put an exclamation mark here to tell it that it's definitely not null i really don't recommend this i'm going to show you what it does and how it works anyway because you might want to use it um map to api version and then we will map it to major and minor which is 0 which is 2 and 0. so with this i basically recreated what i had in the controller level here and here with attributes on startup and if i run this assuming i did this correctly which i think i did and i fire off this request not found yes because we removed the attribute um the route so that was a close one product name it's being picked up by the version here and if i do 1.0 works fine obviously doing a get method on the type i mean i'm sure this is optimized um in memory when the application runs and every subsequent request is fast i probably would do it with attributes i think it also makes it more visible to see what's going on in that controller but i can also see how if you have all of this in a single extension and you register it at once and you have it grouped it can also be very useful for you and with that i covered every major feature of this package of course there's many more but knowing what you learned through this video you should be able to do anything api versioning wise with that package on top of that you can register middleware have more error responses or customize them you can do all sorts of stuff but that's the basics and with that video i believe that you can dive straight into that and make your the visioning that you like so that's it for today thank you very much for watching special next to my patreons for making these videos possible if you want to support me as well you're going to find the link in the description down below leave a like if you like this video subscribe for more content like this and ring the bell as well and i'll see you in the next video keep coding
Info
Channel: Nick Chapsas
Views: 61,520
Rating: 4.9667358 out of 5
Keywords: Elfocrash, elfo, coding, asp.net, .netcore, dot net, core, C#, how to code, tutorial, asp.net core, js, csharp, rest api, lesson, dev, microsoft, microsoft mvp, .net core, nick chapsas, chapsas, asp.net core 3, .net core for beginners, .net 5, asp.net core 5, asp.net core versioning, versioning, api versioning, .netcore api versioning, web api, web api versioning, Elegant API Versioning in ASP.NET Core, dotnet, .net
Id: iVHtKG0eU_s
Channel Id: undefined
Length: 21min 27sec (1287 seconds)
Published: Thu Jan 21 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.