Win a flower (🌹) or copy of Real-World Software Development: A Project-Driven Guide to Fundamentals in Java (📚) this week in the Agile and Other Processes forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Liutauras Vilda
  • Knute Snortum
  • Bear Bibeault
master stewards:
  • Devaka Cooray
  • Jeanne Boyarsky
  • Junilu Lacar
garden masters:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
  • salvin francis
gardeners:
  • Tim Holloway
  • Piet Souris
  • Frits Walraven

Api versioning for a SpringBoot/Kotlin project (with Swagger)

 
pioneer
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I have been working on a SpringBoot/Kotlin (and Swagger) project and I am looking at ways to implement API versioning. I have discarded URI and through Parameters versioning (for obvious and well know reasons I am not going to repeat) and I am looking into Content Header and Accept Header/Content Negotiation approaches and I would like to know whether there are any libraries i can use? Is there any good available example I can follow? Another very trivial question I have is, when you implement API Versioning, do you solely do for GET requests or is it also extended to POST, PUT and DELETE requests?

Thank you
 
garden master
Posts: 11467
247
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know about libraries to do content negotiation, but why would you need one? Can't you just annotate different versions of methods with different @RequestMapping annotations that have the consumes and produces properties configured differently? Something like this:

I'm not a fan of using the Content-Type and Accept headers for this approach though. I'd rather use a custom headers. You can do this with the headers property of the various @RequestMapping annotations.

Geane Norm wrote:Another very trivial question I have is, when you implement API Versioning, do you solely do for GET requests or is it also extended to POST, PUT and DELETE requests?


If you're doing it for GET, then why not for the other verbs? What makes them special?
 
pioneer
Posts: 1816
12
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
For content negotiation in Spring Boot application, you can add the following dependency to the pom.xml.

With this dependency, you can switch between JSON and XML.
 
Stephan van Hulst
garden master
Posts: 11467
247
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think that's necessary. Spring supports both JSON and XML bindings natively, and all you need to do is configure what content types your controller actions consume and produce.
 
Geane Norm
pioneer
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:I don't know about libraries to do content negotiation, but why would you need one? Can't you just annotate different versions of methods with different @RequestMapping annotations that have the consumes and produces properties configured differently? Something like this:

I'm not a fan of using the Content-Type and Accept headers for this approach though. I'd rather use a custom headers. You can do this with the headers property of the various @RequestMapping annotations.

Geane Norm wrote:Another very trivial question I have is, when you implement API Versioning, do you solely do for GET requests or is it also extended to POST, PUT and DELETE requests?


If you're doing it for GET, then why not for the other verbs? What makes them special?



Thank you for your reply, much appreciated. I am very new to API versioning, so most of my questions are rather trivial. I am currently implementing a content negotiation approach and I have come across the following:


https://github.com/tuidx/api-versioning-sample

It looks like an interesting approach and I have tried to apply it to the current implementation. My main doubt resides in what the @RequestMapping should have as opposed to the @GetMapping (for example). Also, another issue is that my produces attribute already contain the following information:



so perhaps I can do something like:



First attempt to implement something along these lines: https://github.com/tuidx/api-versioning-sample :

//const val for vnd.example.library+json;v=2

and at the level of each @GetMapping:



Question is, should I have the produces at the @GetMapping, such as: produces =


What is your view?
 
Stephan van Hulst
garden master
Posts: 11467
247
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Geane Norm wrote:My main doubt resides in what the @RequestMapping should have as opposed to the @GetMapping (for example).


I'm assuming you mean the @RequestMapping annotation at the top of the controller. @GetMapping is a specialized subtype of @RequestMapping that is equivalent to @RequestMapping(method = RequestMethod.GET). Putting a @RequestMapping (subtype) on the controller is equivalent to putting that annotation on every controller action. Typically you put sensible default values at the controller level, and override the defaults at the method level.

If you have a controller that only contains actions for a specific version of your API, it makes sense to configure your versioning at the controller level. If your controller contains actions for mixed API versions, you configure the versioning at the method level.


This is not valid annotation syntax, and the content-type of the response would also not be a valid MIME-type. Why do you want to prepend the application/json MIME-type? It's already implied by the +json part.

and at the level of each @GetMapping:


You don't need to do this if this is already the default value for the headers property at the controller level. It's also not valid annotation syntax.

Anyway, I prefer the approach using the custom header, because it is less likely to break the JSON message readers than when you use a custom MIME-type for the Accept and Content-Type headers. If you have a controller that is dedicated to just one version of your API, and all methods only work with JSON, you could declare it like this:
 
Geane Norm
pioneer
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for your reply, once again It makes sense and I see your point. I wanted to ask another question, this one is more high level one. When you do versioning, do you simply have multiple versions of your controllers? What about if the underlying model representation changes, would you recommend to have different versions of the model and or dto?

Thank you,

 
Stephan van Hulst
garden master
Posts: 11467
247
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For new major versions that are not backwards compatible I usually deploy a completely separate application.

As far as I'm concerned, the business layer and the service interface are separate from each other. If you have to change your business layer to implement a new user story, but you can access it with the same service API, then you can obviously keep the service interface the same.
 
Yeast devil! Back to the oven that baked you! And take this tiny ad too:
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!