Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for versioning RESTful APIs #33599

Open
xezzon opened this issue Sep 26, 2024 · 4 comments
Open

Add Support for versioning RESTful APIs #33599

xezzon opened this issue Sep 26, 2024 · 4 comments
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: waiting-for-triage An issue we've not yet triaged or decided on

Comments

@xezzon
Copy link

xezzon commented Sep 26, 2024

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.
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Sep 26, 2024
@bclozel bclozel transferred this issue from spring-projects/spring-boot Sep 26, 2024
@bclozel bclozel added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Sep 26, 2024
@quaff
Copy link
Contributor

quaff commented Sep 27, 2024

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.

@xezzon
Copy link
Author

xezzon commented Sep 27, 2024

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

@livk-cloud
Copy link

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

@bclozel
Copy link
Member

bclozel commented Sep 30, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: waiting-for-triage An issue we've not yet triaged or decided on
Projects
None yet
Development

No branches or pull requests

5 participants