10

I am looking for good tools to support support changing the version of the model used in REST services. My dream tools would do something like:

  • My pojo + version 1.0 config/transformer => Service available with 1.0 of my model
  • My pojo + version 1.1 config/transformer => Service available with 1.1 of my model

In my particular case I do not need to do the reverse transformation as my REST service will only provide lookup of data and never store stuff, but I don't mind using a tool doing both:-)

A solution I am considering is adding custom annotations in my pojo (version + name) and make a code generator that will generate JSON/XML based on my pojo based on the version number. Though here I feel like I am re-inventing the wheel.

Edit: Here is an example of a change that can be done from version 1 to version 1.1:

Version 1: Person firstname lastname

Version 1.1 Person firstname lastname birthdate

If you access the API with version 1.0 you do not get the birthdate attribute - it is only available in version 1.1. I want tool support for making these services available, where I can configure that granted that my pojo (which is currently like the 1.1 version), I want to make available a 1.0 version that does not show these values.

Other legal changes to the model could be to delete an attribute or to rename an attribute (or even rename an entity).

Edit 2: Digital Joel mentioned in a comment that for a discussion on versioning the API you should go read https://stackoverflow.com/posts/9789756/.

The easy way out of versioning is ofcourse to not make backward breaking API changes, but business change so this is not always possible. My interest is on how to make these changes simpler to handle, therefore my question.

Edit 3: I've looked for tools that might help the process, but still nothing that connects this in a good way with rest. Here are the links that I have found so far:

Community
  • 1
  • 1
Knubo
  • 8,333
  • 4
  • 19
  • 25

5 Answers5

9

As mentioned in one answer, there may be no tools available for which does automatic versioning of APIs.

We can address this challenge with two step approach :

1) Versioning info of API There are many debates on best practice. two most popular are :

(i) URI redesign - putting version info in URI like
http://something.com/v1.0/resource1/ or
http://something.com/resource1?ver=1.0

(ii) Using HTTP Header - putting version info in Accept/Content-Type
header keeping URI intact like 
#
GET /something/ HTTP/1.1 
Accept: application/resource1-v1.0+json

2) Multiple versions of same pojo using json/xml library

Once version info is with us we have to generate resource accordingly. There are many json and xml library with which we can maintain multiple versions of same pojo and serialize only required attributes based on version. Google gson java library works great in this. Check https://sites.google.com/site/gson/gson-user-guide#TOC-Versioning-Support

public class Person{

@Since(1.0)
private String firstname;

@Since(1.0)
private String lastname;

@Since(1.1)
private String birthdate;

}
shashankaholic
  • 4,122
  • 3
  • 25
  • 28
  • Excellent response. The gson library looks like a good match. – Knubo Mar 27 '12 at 23:39
  • 3
    Nice one! I didn't know gson had versioning support. You deserve the bounty. – digitaljoel Mar 28 '12 at 17:21
  • I'll for sure shell out the bounty when the time runs out and no one beats his answer :-) – Knubo Mar 28 '12 at 19:24
  • yeah, I meant he deserved it over my answer so I was voting for it so he had more votes than me so even if you didn't award it he would get it. – digitaljoel Mar 29 '12 at 00:32
  • Likewise, I would like to try this myself. The only other solution I could think of would be to use an [ESB](http://stackoverflow.com/questions/5479928/web-services-versioning-is-esb-overkill) to intercept and convert requests. – aliasmrchips Mar 29 '12 at 01:20
1

I'm not aware of any tools for automatically versioning your RESTful API. For a big discussion on versioning REST you should read Best practices for API versioning?.

I spent a fair amount of time looking into this when planning a RESTful API, and we came to the conclusion that we would evolve in a manner that does not introduce breaking changes. If a breaking change is required then we would expose it as a new resource rather than try to use version information in a custom header or mime type. But, to your question, that means work on my side, which is even more incentive to keep from making breaking changes.

When it comes to tools, I seriously doubt you are going to find something that can automagically make the changes required for supporting multiple versions of your RESTful API. It would require a tool that understands the differences between 2 versions of your model, and all of the interactions in your API.

If you are conforming to the HATEOAS principle of REST then all destinations from a given location are also included in the response, in which case you could use something like the REST support the request mappings in Spring MVC to keep the version number in all of your URLS given a single entry point from the client, but you would still need to maintain the controllers and model for each version.

Community
  • 1
  • 1
digitaljoel
  • 26,265
  • 15
  • 89
  • 115
  • Thanks for the reference - I'll add it to my question as it is important that people finding this question first understand how to version the API before they tackle the problem on how do this in your code. – Knubo Mar 23 '12 at 07:10
1

This is not the answer you may be expecting since I do not use an open source external tool to do the heavy lifting for me. I use my own tool.

I use Jersey. I use /vx/ included in my @Path declarations.

Since REST apis represent contracts I do not trust automatic creation. Yet, I have done an XLST tool in a not very complex maven plugin.) I maintain the succinct xml version and transform into a Jersey class in gensrc.

I have found that v1 has a certain path and matrix/query parameters unique to the design at the time. When I develop v2 I often find that I need to support additional parameters or restructure my urls for better understanding. I just need to change the xml file.

My generation engine will create my Jersey layer with MyAPIv1.java and MyAPIv2.java and annotate according to the need of the time.

So I want to retain control of the versioning and having an auto/tool could be detrimental.

Again, using a spec is a great way to fully control, yet not fully implement thin layers.

So no cigar here, but this may be helpful.

Jaime Garza
  • 483
  • 1
  • 4
  • 10
0

just a thought, but wouldn't it be nicer to make your api backwards compatible; then you only need versioning for your code repository and that's much less hassle ?

Tom
  • 4,096
  • 2
  • 24
  • 38
-1

Are you talking about something that's going to version this for you in the development world (maintaining versions of your api for giving to users) or in the live server world (content negotiation at runtime)?

For the former, look at tools like maven, ivy, gradle.. that's what they are for. I personally use maven because it's the one I know the best, but they all allow you to publish jar files with versions for just this purpose.

Rick Mangi
  • 3,761
  • 1
  • 14
  • 17
  • I am talking about versioning the API. – Knubo Mar 20 '12 at 18:42
  • If you're looking to package versions in jar files to distribute to users to build against, look at maven. – Rick Mangi Mar 20 '12 at 19:36
  • With regards to my question - it does not relate to maven - I am looking for tools to versioning the REST web service API, not how to version the components used to build the system. – Knubo Mar 21 '12 at 06:40
  • I guess it's not clear what you mean by "version the api". An API is just a contract between you the service developer and the clients who want to use your service. That's why I asked if you meant versioning the jar files you're distributing, or versioning on the server side so you can detect if a client is requesting a resource using version 1.0 or version 2.0 of the API (content negotiation) – Rick Mangi Mar 21 '12 at 14:29