Comments (4)
Great link that summarizes the approaches with the pros and cons of each. I've seen the media type negotation approach before, but had forgotten about it. I would surmise that there are actually 4 common API versioning schemes:
- Version by URL path (ex:
/api/v1/foo
) - Version by URL query string (ex:
/api/foo?api-version=1.0
) - Version by HTTP header (ex:
api-version: 1.0
) - Version by media type negotiation (ex:
accept: application/vnd.mycompany.myapp-v2+xml
)
This set of libraries uses option 2 by default. It doesn't necessarily mean it's the best approach as such a statement is highly subjective. Aside from aligning to the Microsoft REST versioning guidelines, I would say that option 2 also has the following benefits:
- Easiest option for all clients to consume (ex: desktop apps, mobile apps, web apps, etc)
- Provides a stable URL over time since the query string is not part of the resource path
- Easiest option for service authors to integrate without breaking their clients
- Flexible option for advanced scenarios where a gateway might need to route a request based on version
From a RESTful perspective, I believe that the stable URL constraint is pretty important. Different versions of a resource are not different, logical resources, but rather different representations. The query string never identifies a resource. In that way, the query string and media type methods are similar.
While I have obviously have an opinion, the design goals were not to pigeon-hole service authors into my method of API versioning, but instead give them choices with a few out-of-the-box implementations. API versioning using media type negotiation can be supported, but I'm not sure it can be done out-of-the-box. The reason is that there is no established convention or format for the media type value. In your example, the code would have to know how to extract "2" from the "v2" fragment of the header value. All is not lost however.
The design of the library abstracts how the raw API version is read from a HTTP request via the IApiVersionReader interface. All of the built-in support goes through this component. There is never any assumptions about how to get the raw API version from a request. It was straightforward to a create a couple of default implementations that understand how to read an API version from a query string or header value. The default readers, however, do not manipulate the extracted value. They assume the value read is in the correct form.
An implementation to support API versioning by media type negotiation in Web API might look something like:
public class MediaTypeApiVersionReader : IApiVersionReader
{
private const string Pattern = @"-v(\d+(\.\d+)?)\+\S+$";
public string Read( HttpRequestMessage request )
{
// TODO: consider what happens if Accept is provided multiple times or with quality
var mediaType = request.Headers.Accept.Single().MediaType;
var match = Regex.Match( Pattern, mediaType, RegexOptions.RightToLeft );
return match.Success ? match.Groups[1].Value : null;
}
}
Now you just need to tell the configuration that you want to read the API version from the request a different way:
configuration.AddApiVersioning(
options => options.ApiVersionReader =
new MediaTypeApiVersionReader() );
Everything else about how the library is used is unchanged. If you can think of a standard way of using media types for API versioning, I'm willing to consider its inclusion. For the time being, it is possible to support, but left up to service authors to implement albeit with minimal code.
from aspnet-api-versioning.
I missed the query string as a fourth option. Interestingly I found myself agreeing with your reasoning for it being the default.
Unfortunately the vendor tree MIME type standard does not define how a version should be specified. However, I do think that the internet has come to an understanding about how these vnd MIME types can be used as there are numerous articles out there using the same format with the version in the same spot.
Your sample code for IApiVersionReader
seems reasonable. You may want to move away from regular expressions for performance reasons, although you'd probably want to test that first. I'd agree with leaving this as an exercise for the developer to implement IApiVersionReader
. I might add an implementation of IApiVersionReader
which takes a delegate though.
from aspnet-api-versioning.
When we just talk service semantics over HTTP, using a vendor tree MIME type makes sense. The realization of that in code by service authors requires more work that most are willing to put in. For example, I completely glossed over the fact that in either of the current ASP.NET stacks, the service author would still have to define custom media type mappings.
The example API version reader was in no way meant to represent production code, which could also be some optimized parsing routing or a dictionary that maps content type to version. I considered just having a callback method in the options or having a DelegatingApiVersionReader class, but it didn't seem it would be used all that often. Furthermore, creating a class with a single method is not a huge effort and it assists in the intention-revealing readability of the code.
from aspnet-api-versioning.
Re-opening this issue so that it can be linked to the forthcoming PR.
After quite a bit of thought, there is a way to make this work standard and out-of-the-box using a media type parameter. While defining custom media types would be technically possible, the platform setup requires more effort than most are willing to put in. Furthermore, I think we would agree that although there is nothing wrong with defining custom media types, we would want to avoid using them.
See #70 for an overview of how it will work.
from aspnet-api-versioning.
Related Issues (20)
- AddVersionedApiExplorer not working in Asp.Versioning HOT 5
- VersionedApiDescriptionProvider does not set the correct SunsetPolicy to ApiDescription instances HOT 1
- Using ApiExplorerSettingsAttribute together with ApiVersionAttribute produces unexpected number of ApiVersionDescriptions HOT 5
- Asp.Net Core WebApi - AWS ECS Cluster Authentication failure HOT 2
- [Versioned Clients][API Notifications] Fails to read new versions when available HOT 2
- Swashbuckle documentation inconsistent with examples HOT 2
- AssumeDefaultVersionWhenUnspecified does not work correctly if ApiVersionNeutral is used in the controller HOT 2
- swagger.json file not found after update HOT 9
- My API is not displaying all the versions. HOT 4
- Improve docs for HeaderApiVersionReader
- Add synonym to `AddMvc` method. HOT 7
- CurrentImplementationApiVersionSelector behaves differently based on whether an operation still exists on latest API version HOT 3
- The error 'code' is not included in the error response when using AddErrorObjects() HOT 2
- .NET 8 ASP Versioning is allowing any version number to be passed in to api request and returns data. HOT 5
- Native AoT trim analysis warning : WithLinkGeneratorDecorator
- Using URL segment versioning breaks Swagger generation HOT 3
- Documentation: Default value for ApiVersionReader is misleading
- SBOM Report for Infor ( GRC Product )
- ApiVersionMatcherPolicy Invalidates valid candidates HOT 1
- Support Microsoft.AspNetCore.OData v9 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aspnet-api-versioning.