Expected effect

Route URLs to different methods based on some characteristics of the URI, request parameter, request header and so on. These should be configurable.

Known solutions

https://medium.com/@AlexanderObregon/a-guide-to-versioning-apis-in-spring-boot-329aae1c495f

I am not satisfied with this solution because it breaks the pattern Convention Over Configuration. I had to do a lot of hard coding.

Reference

https://docs.micronaut.io/latest/guide/index.html#apiVersioning

Expected solution

  • Add the element version for @RequestMapping and related annotations (@GetMapping, PostMapping, etc.). (recommended)
  • Add the annotation @Version, as in Micronaut.

Comment From: quaff

IMO, versioning is against all APIs not particular API, you should create multiple contexts and mapping them to different API base url such as /api/v1/*, /api/v2/*, even more, you should create dedicated application per version.

Comment From: xezzon

I don't think we should assume that users will only use this one way and that the others will be abandoned.

Comment From: livk-cloud

I think it's a good proposition, Although it is currently possible to achieve this by extending RequestMappingHandlerMapping and customizing RequestCondition.

Comment From: bclozel

Thanks for raising this.

As far as I can see, this article lists several ways of dealing with API versions in a Spring Boot REST-like application: 1. using a query parameter, like GET https://example.org/api/users/42?version=1 2. using a path prefix, like GET https://example.org/api/v1/users/42 3. using a custom header, like X-API-Version: 1 4. using content negotiation with a custom content type like application/vnd.io-spring.v1.users+json

It seems that this is not really promoting a version concept in the application itself: it cannot be injected as a method argument, versions are opaque strings and cannot be compared, etc. In the end, this looks like an additional mapping constraint for MVC endpoints. Most of these can be implemented already with custom annotations extending from @RequestMapping, but arguably with a more "manual" approach.

Interestingly, the @Version chosen by Micronaut doesn't apply to solution 4) as it's more hands on with the actual content type and one would need specific assumptions about version strings. I guess this can be implemented with a custom RequestVersionResolver.

We could consider making this easier for developers. I do have some concerns though: * opinions vary widely on best practices as we can already see with comments here * there are no shared concept of a "version"; it's merely an opaque string * as we can see with @Version, this information acts on the request mapping but depends on out-of-band configuration. Looking at a controller endpoint declaration, it's not obvious what is the expected request format. This can create significant challenges for existing, popular features.

We're going to discuss this as a team.