Implementing Modern API Versioning in .NET

  Рет қаралды 70,802

Nick Chapsas

Nick Chapsas

Күн бұрын

Пікірлер: 76
@LachlanWood-gy1ut
@LachlanWood-gy1ut Жыл бұрын
Thanks for another great video Nick! I've recently implemented versioning on an existing API and utilised the mentioned package in this video. I wanted to share my experience here to help others if they are in the same situation. The situation is that when we developed our APIs, we made a decision to not utilise the `[ApiController]` attribute on our endpoints so that we could gain complete control over how we validate the models and form our responses. If you are in a similar situation and follow all the recommended steps when configuring this versioning package, it will not behave as expected. After a few hours of fiddling, reading through a bit of documentation and class annotations, I found that in the options there is the `options.UseApiBehavior` which you can set to false to include the controllers that don't have the `ApiController` attribute.
@carstenberggreen7509
@carstenberggreen7509 Жыл бұрын
Awesome overview, efficient and useful!
@00wiking
@00wiking 2 жыл бұрын
I like your videos, sometimes you touch interesting for me tasks. You are the one of youtubers that I must watch in slow motion btw ;)
@mihaimyh
@mihaimyh 2 жыл бұрын
Hi Nick, a video an assembly versioning will be nice.
@julianlumetsberger4151
@julianlumetsberger4151 10 ай бұрын
Great Video! Very elegant way.
@andriisnihyr6497
@andriisnihyr6497 2 жыл бұрын
So cool, thanks for sharing! I didn't know this package exists.
@raptorjesus3396
@raptorjesus3396 2 жыл бұрын
We literally do not use the API version concept at service level, instead we run the service multiple times with different versions. The proxy handles the /api/v1 and /api/v2 portion of the url. Once a new API version is introduced the branches for other API versions are maintenance only. Moving the API version concept to service level is just cluttering already dense api controllers up even more. I personally advice handling API versions in NGINX/Apache.
@Re5pectful
@Re5pectful 2 жыл бұрын
And you are running multiple services , with different versions, against the same database? How can you introduce changes to the datamodel?
@raptorjesus3396
@raptorjesus3396 2 жыл бұрын
@@Re5pectful the data layer is distributed over multiple, separate projects, they mostly export in the repository pattern. These are imported by the API. In case an exported model is changed, the all active API versions are adapted to work with the changes. They reside in different branches of the repo, so most of the time we can in fact cherrypick commits from the newest version, only sometimes we need to actually patch anything. A good 95% of all changes are simply additional fields, for which the API code doesn't even need to change to support, since they are defined in separate projects.
@Goose-jf2cl
@Goose-jf2cl Жыл бұрын
Great video, quick and very informative.
@andersjuul8310
@andersjuul8310 9 ай бұрын
Love it. Keep teaching 🙏.
@arithex
@arithex Жыл бұрын
How it started: just make a "/v2/foo" endpoint How it's going: add dozen lines of boilerplate, dependency injection and a new 3p package dependency why do we keep doing this to ourselves? is nothing allowed to be simple?
@nickchapsas
@nickchapsas Жыл бұрын
It's as complex as your requirements. If they aren't then you don't need it.
@Ricardo-qw8yh
@Ricardo-qw8yh Жыл бұрын
great explanation, thanks a lot 👍🏼
@matthewhamby5749
@matthewhamby5749 Жыл бұрын
What is the link for the documentation to the swagger classes?
@pablogarnica6608
@pablogarnica6608 Жыл бұрын
Great content. thanks for sharing your knowledge!
@pbreslinltd
@pbreslinltd 9 ай бұрын
Awesome video... How do you handle sub versions, minor and patch... I would want to track all changes that are non-breaking as minor and patch changes and have an endpoint call to the complete version which would return V1.15.2 but when they use the API on all the other endpoints, and I use the "v{version:apiversion}" in the URL segment, it should only care about the major...
@florianliefers3593
@florianliefers3593 2 жыл бұрын
With your talking speed you could read out your patreons at the end in realtime 😅. Nice video 👍🏻!
@larsp5109
@larsp5109 2 жыл бұрын
And I always watch these videos at at least 1.25 times the original speed… 😂
@paulpeeters
@paulpeeters 2 жыл бұрын
How should one implement a V2 API that uses most or many of the V1 endpoints except some additional and/or some modified for the V2 version? And the same when other versions are created. We want the consumer of the API to specify either V1, V2, V3 for all of the API endpoints he will be using.
@Any1SL
@Any1SL 2 жыл бұрын
Your only spans sweater is hilarious
@dputra
@dputra Жыл бұрын
They need to mark the old packages as deprecated. I wasn't aware of the name change to Asp.Versioning for a long time until I found an article written about it.
@lexer_
@lexer_ 2 жыл бұрын
I have a question about this which actually also applies to many of your other videos. This seems like it is needlessly complicated. Your initial example without any library was orders of magnitudes easier to understand and also just outright much less code. The depth of knowledge of the library needed is arguably much more than just coding the operations you need by hand. There are examples like mediatr that legitimately seem like they would simplify the core problem. It does a lot more more work for the library consumer than it creates in implementing it. But this seems like it is a needlessly complex abstraction for a very simple problem. The only good argument in favor of libraries like those is that the user is less likely to implement API versioning in a horrible way. But in my experience this goal of preventing bad programmers from writing bad code by getting them to use good libraries never works. Bad programmers will find ways of using good libraries in the most horrific ways anyway so you really incur the cost of both, the bad programmer and the additional complexity of the library. In my opinion the far better solution instead of implementing these libraries is to just spend the time to properly train your developers in fundamentals and give them the time they need to really grasp the concepts properly and to then let go the people that just don't have the mindspace or interest to learn. I am of course wording this point more sharply and one-sided than I really see it. There is a lot of grey area here of course. But I would love to see you address this kind of somewhat one-sided critical view of these types of libraries and I feel like everyone could profit if you could make good points in favor of using them.
@nickchapsas
@nickchapsas 2 жыл бұрын
As someone who’s worked with versioned APIs for years, I can guarantee you that the first approach is very epidermic and falls apart very easily. The depth of the library goes as deep as the knowledge of versioning itself. Everything that the library offers is everything that every developer MUST know to implement versioning. You can skip the library but as your code evolves, you’ll understand that you just did what the library already does, but probably worse
@lexer_
@lexer_ 2 жыл бұрын
@@nickchapsas Oh, don't get me wrong. I fully understand why this is useful and beneficial. I mostly wanted to steelman a common counter argument here. It also really depends on the use-case of course. If the entire project could be rewritten from scratch in an hour or two, learning this library and all its features is complete overkill in comparison. But most projects have the tendency to just keep growing over time and starting with proper versioning from the beginning is almost always a positive.
@georget10i
@georget10i 2 жыл бұрын
This is not a criticism against Nick, but I agree. The more I code, the more I dislike using needless complexity. There are so many latest trendy blog article developers in the industry who just love throwing all kinds of Nuget packages and unnecessary complexity into projects; wiring them up and doing all these smart, needlessly complicated things without actually considering the time it will take to maintain and understand it when others need to troubleshoot it. Even Mediatr, many just throw it in "for future". They look at your method and "Oh, my lord! Your method has 20 lines of code in it!!? No, no, we need to fix it. Download these Nuget packages, and we abstract it, and we abstract it and we abstract it and wire it all up. And there, 20 lines down to just 1 line". Except now no one understands how it all magically works, bar that one person, who now wants to move to other cool things; no one will maintain it and there are extension methods and classes all over the place. This is an extreme example, but I hope you get the point. KISS!
@EtienneBotek
@EtienneBotek 2 жыл бұрын
@@lexer_ I agree with the general argument that sometimes a small library is too much of an overhead cost because you need to learn it, maintain its integration etc. But if the package is well thought like it seems here, it seems easy to learn and not much of a cost. If you have multiple projects then you gain by using the same standard everywhere.
@commonsensesoftware
@commonsensesoftware 2 жыл бұрын
In general, I agree these assertions. It's not that hard to abuse any library in obtuse ways that were not intended. Case in point, "AssumeDefaultVersionWhenUnspecified" was ONLY ever meant to support the backward compatibility scenario where you bring in formal API versioning semantics that would otherwise break existing clients. It was never meant to be a mechanism to omit specifying the version and then arbitrarily choosing it on the server. That is flat out wrong IMO. What is the point or value of versioning at that point? There is no substitute for education and learning. One of my favorite assertions from good 'ol "Object Thinking" is that we don't need better CASE tools, we need better engineers. This is especially true in web APIs. It's amazing to me how many people claim they are/have built a RESTful API, but cannot define what makes it RESTful. They've never read Fielding's dissertation or even Chapter 5 on REST. If you don't even know what REST is, how an you say you've built a REST API? REST != HTTP A lot of the design decisions that went into API Versioning hovered around common principles. I wanted to support the 80% with minimal configuration and it should feel largely like it just bolted on metadata to your APIs without having to learn a whole bunch of new ways of doing things. When you fall into the 20% bucket, then there are a bunch more options you can leverage. ...and now for a bit of controversy 😄 Versioning by URL segment is just wrong. Yes, it's popular. Yes, you "can" create a web API that way. It is, however, not RESTful. If you don't care about REST - end controversy. Versioning by URL segment violates the Uniform Interface constraint. The constraints are not optional. The URL path is the resource identifier; however, "v1/hello" and "v2/hello" imply that they are different. They are not different resources, they are different "representations". This is no different than if you had "application/json" vs "application/xml". The path to the resource is the same, even if the resource looks completely different over the wire. This isn't my dogma; it's what Fielding defined. This is also why Fielding says the only proper method of API versioning is by media type (which the GitHub API does BTW). It's hard to argue with the guy that created these rules. Using the query string is pragmatic without violating any constraints. The URL method comes with a litany of other problems such as hypermedia. One of these days I get a post or vid out that breaks it all down.
@Karan-ur9ym
@Karan-ur9ym 5 ай бұрын
Is there a way to find out differences or compare the 2 versions. For example if client is using version1 and wants to use version2 but not sure what differences are there. Is there a way to see what changed between version1 vs version2
@salorsilvar5908
@salorsilvar5908 Жыл бұрын
Thanks so much sir
@jcampos
@jcampos 2 жыл бұрын
I'd love to find any tutorials/blog posts or any guidance about how to organize your code (different versions of same APIs, different DTOs, etc.) when doing versioning. I've been using API versioning on .NET for a long time, but I can't find any good "code organization" for it, specially if you don't just want to have full copies of the API (when nothing hasn't been modified) on different namespaces
@jcampos
@jcampos 2 жыл бұрын
@@SlavomirDanas Yes, I understand that... I'm wondering how do you manage the code (the different code files, folders, etc.) when you need to have different DTOs and many endpoints changing versions (specially on large APIs)
@jcampos
@jcampos 2 жыл бұрын
@@SlavomirDanas I don't... but it's one of the strategies I tried for very small APIs where multiple versions had to be maintained (and I didn't like it, but neither I've liked ANY of the strategies I've followed, that's why I'm looking for more info on the subject)
@jcampos
@jcampos 2 жыл бұрын
@@SlavomirDanas I don't see how defining the controller contracts in interfaces would help with versioning (the opposite in fact, what if a specific endpoint version changes the contract? i.e., if 'x' endpoint on version 2.0 receives a different set of parameters than in version 1.0?), also, what would you do for DTOs with different versions? Add the version name on the type? Also, what if only one endpoint changes from version to version in the whole controller (which may have many different endpoint actions?) And again, that's only if talking about controllers (this video is specifically about minimal APIs, which don't use them, but same thing, you'll end up grouping endpoints "somehow", be it a controller or any other means)
@jcampos
@jcampos 2 жыл бұрын
@@SlavomirDanas Yes, I understand how this package works... again, I'm still unsure (I've tried many ways over the years, but haven't found a satisfactory one) how to manage the code, multiple versions of slighltly different DTOs, etc., when you have to maintain several versions on the same project... it's not using the API versioning tool that I don't get 🙂
@commonsensesoftware
@commonsensesoftware 2 жыл бұрын
There's no one universal answer. The "Copy, Paste, Replace" (CPR) method on a folder might seem tedious, but there are a few things to consider. It's super important that new versions not affect the old ones (e.g. introduce a breaking change). For that reason, inheritance is a bad idea. You can't "uninherit" a method. You should always have a sound versioning policy. If your policy is "N-2", then having a few folders, even with some duplicated code, isn't all that bad. Pushing out generic functionality into other collaborators can also reduce code duplication. The CPR method combined with the "VersionByNamespaceConvention" is as about a close to zero-touch as you can get. New versions are copied to new folders from a well-known baseline and old versions are simply deleted. Sharing models (DTOs or otherwise) can be cumbersome. A nice benefit of OData is having an Entity Data Model (EDM) which separates what the resource looks like over the wire versus what the code looks like. For simple add/remove changes between versions, this makes it very easy to have a single implementation that is mapped different ways. Now that the API version metadata is completely divorced of any part of ASP.NET (into "abstractions"), I will consider future support where you might achieve a similar result by applying version metadata to non-OData scenarios. It's something I would seriously considered for 8.0 later this year. For example: public class Person { public string FirstName { get; set; } public string LastName { get; set; } [ApiVersion(1.0)] public string Email { get; set; } } This would be configurable via attributes or by convention.
@brunocandia703
@brunocandia703 Жыл бұрын
Hi Nick, nice video. This packages also applies to an Http triggered Azure Function? As far as I know the package that is used when dealing with an azure function is not that flexible. For example the Swagger UI generated does not contain a drop-down list to be able to filter by the different versions.
@Spirch
@Spirch 2 жыл бұрын
missing link to your previous video in the description
@nickchapsas
@nickchapsas 2 жыл бұрын
Added
@Cicatka.Michal
@Cicatka.Michal 2 жыл бұрын
Thank You for the great content. :) I'd be really interested in a video that deals with testing a thread safety in C#. Is that event possible?
@ivanomatrisciano3828
@ivanomatrisciano3828 2 жыл бұрын
How would you handle translations in a front-end?
@KibbleWhite
@KibbleWhite 2 жыл бұрын
Nice work, I like it !
@bakkupavan
@bakkupavan 4 ай бұрын
Hi Nick, great video but I am getting an error at app.DescribeApiVersions() IApplicationBuilder does not contain a definition for DescribeApiVersions. Please help.
@JtendraShahani
@JtendraShahani 9 ай бұрын
Can someone please point me to the article Nick is referring. Don't know how to implement both ConfigureSwaggerOptions & SwaggerDefaultValues.
@TrungTran-le2ht
@TrungTran-le2ht 11 ай бұрын
just a small question, how do u reduce the duplicated code among versions ?
@NathanZKhupe
@NathanZKhupe Жыл бұрын
How do we combine this with the IEndpointDefinition approach?
@purejoymind1705
@purejoymind1705 10 ай бұрын
Does this work with non-minimal apis?
@keeganfargher6418
@keeganfargher6418 2 жыл бұрын
How can you version your business logic? I struggle when we make breaking changes to our services or models.
@nickchapsas
@nickchapsas 2 жыл бұрын
Different endpoints can call to different services.
@lolroflxd
@lolroflxd 2 жыл бұрын
You can also use the Obsolete attribute and instead of rewrite for example a method that is obsolete, you can add it as a new method with different overloads or another name. This way your consuming apps can still use the obsolete stuff, without break everything after an update.
@PelFox
@PelFox 2 жыл бұрын
You use obsolete flags, keep old code working with the old endpoint and decide on a date to obsolete the v1 completely. It's generally there to allow your consumers to have time to make the change.
@commonsensesoftware
@commonsensesoftware 2 жыл бұрын
I agree with these all. Marking an API version "deprecated" is one way to express that client should stop using a particular version and that it will one day go away. The new "sunset policies" feature will allow to explicitly communicate the date and time when the version will be sunset as well as any supporting documentation such as a public HTML page that outlines your versioning policies.
@ekay
@ekay Жыл бұрын
Hi, I just wonder how to implement it if we separate the endpoint from Program.cs (like your video) in other folder such as EndpointDefinitions?
@danfrench35
@danfrench35 Жыл бұрын
Just trying to work this out myself, did you ever find a solution?
@NitheeshShrivaths
@NitheeshShrivaths Жыл бұрын
Is there a way where I can control the contents in program file based on a version I want to use ? I need AzureAD authentication in one version and Auth0 authentication in another.
@mikaelsyska
@mikaelsyska 2 жыл бұрын
Funny that is sometimes showed the version as 1.0 and 2 ... Not 2.0 ... 😉 When returned. Any reason for that?
@CuriouslyContent
@CuriouslyContent Жыл бұрын
Hi Nick, question which also applies to your first video: can you have all 3 approaches combined? That would require that you could have multiple mappings to the same block: app.MapGet(["v{version:apiVersion/hello", "hello"], ()=> ..... etc. Is this possible? I'm sure we could all figure this out, but an answer would save everyone time ;-) Love the Channel!!!
@youssefwael8
@youssefwael8 2 жыл бұрын
Do you plan to make a video about OData in the future?
@krccmsitp2884
@krccmsitp2884 2 жыл бұрын
Is OData still a thing nowadays?
@commonsensesoftware
@commonsensesoftware 2 жыл бұрын
@@krccmsitp2884 it is. The two biggest implementations are probably read side of NuGet and MS Graph
@youssefwael8
@youssefwael8 2 жыл бұрын
@@krccmsitp2884 I know some companies still using OData
@Odin3411
@Odin3411 Жыл бұрын
спасибо
@tosunabi1664
@tosunabi1664 Жыл бұрын
I wonder how many people are releasing more than v1 of an app to use that package which itself looks adding too much code around/complexity.
@theAutomaTom
@theAutomaTom Жыл бұрын
When you gotta do it, you gotta do it.
@nadirmezhoudi
@nadirmezhoudi 2 жыл бұрын
Hi Nick ,Great video. Can you make a video about LiteDB .? Which is a great library for No-Sql. Embedded Database compared to sqlite.
@sunefred
@sunefred 2 жыл бұрын
Nick Chapsas talks so fast that the sound waves can not keep up with his lips.
@allanwankers2126
@allanwankers2126 2 жыл бұрын
Please share source code
@_jimbarton
@_jimbarton Жыл бұрын
Only person I can't play at 2x speed ahaha
@igor5379
@igor5379 2 жыл бұрын
cool!
@lpsoldier357
@lpsoldier357 Жыл бұрын
This solution seems to break swagger. Anyone else with the same problem?
@carlinzindev
@carlinzindev Жыл бұрын
você conseguiu ?
@JackDjTom6
@JackDjTom6 2 жыл бұрын
Hi Nick, I've seen your amzaing video about foreach loops with Ranges (Adding a BETTER way to loop in C# -> kzbin.info/www/bejne/oJ7Qq2SZftOBpdk) and I tried to loop like this: foreach (var i in -10..-5) but that didn't work since Range doesn't support negative numbers. So I was wondering if you know any way to make this foreach loop work with negative ranges?
ASP.NET Core Web API .NET 8 2024 -1. Create Project + Install
13:31
Beat Ronaldo, Win $1,000,000
22:45
MrBeast
Рет қаралды 158 МЛН
BAYGUYSTAN | 1 СЕРИЯ | bayGUYS
36:55
bayGUYS
Рет қаралды 1,9 МЛН
Try this prank with your friends 😂 @karina-kola
00:18
Andrey Grechka
Рет қаралды 9 МЛН
Goodbye controllers, hello Minimal APIs - Nick Chapsas - NDC London 2023
54:28
Don't throw exceptions in C#. Do this instead
18:13
Nick Chapsas
Рет қаралды 264 М.
The .NET 8 Auth Changes You Must Know About!
10:27
Nick Chapsas
Рет қаралды 149 М.
Why you should version your api endpoints
9:56
Web Dev Cody
Рет қаралды 15 М.
API версионирование: как, зачем и почему?
1:06:12
Settling the Biggest Await Async Debate in .NET
14:47
Nick Chapsas
Рет қаралды 148 М.
The New Global Error Handling in ASP.NET Core 8
13:41
Milan Jovanović
Рет қаралды 48 М.
Forget Controllers and Minimal APIs in .NET!
14:07
Nick Chapsas
Рет қаралды 80 М.
How To Build Feature Flags Like A Senior Dev In 20 Minutes
20:33
Web Dev Simplified
Рет қаралды 110 М.
How To Implement API Key Authentication In ASP.NET Core
17:13
Milan Jovanović
Рет қаралды 36 М.
Beat Ronaldo, Win $1,000,000
22:45
MrBeast
Рет қаралды 158 МЛН