Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST API versioning

Tags:

java

rest

I currently work on a Java based web application. Recently we created some REST endpoints using Spring. The reason for this was because we developed a hybrid mobile app that integrates with our main application via these end points.

The problem is that going forward we are not quite sure how to handle updates. If we update our API, e.g. we change the method signatures of the end point methods or we change the attributes on the DTOs that we return as JSON, then we would have an issue if our mobile users are running an out dated version of the mobile app.

What we want to implement is something that will force our users to update the app if it is out of date. I have seen a lot of mobile apps that do this. So we thought of having an API version for our REST API and then have the mobile app check if the version it is using is the same as the version being run by our server and if not, then force the user to do an update.

The problems we have are:

  1. We only have one version of our server running at any time. So how would we time our releases? What happens in the event that we release a new version of our API and our mobile app but the app store does not yet have the latest version publicly available. Then the user will be forced to do an update but the updated app is not yet available to them.

  2. How do we maintain the API version number? On the mobile app we can just configure that. But on the server it is not great to have to maintain a version number. The reason I say this is what if we make a change to a method signature or DTO, etc, and forget to update this version number manually before releasing? Surely there is a more automatic way to do this where some unique "API key" is generated based on the current definition of the API? We could then use this instead of an API version number.

like image 224
brent777 Avatar asked Aug 28 '15 15:08

brent777


1 Answers

There are a few things you can do.

  1. Architect API versioning in from the beginning. There are 2 common approaches I have seen for this with REST API's: putting a URL prefix like /v1, /v2, etc. before all REST resource end points or using the HTTP Accepts header to negotiate versions. There are religious wars on which one is right. It's your API. Do what you think is right.
  2. Abstract out business logic from API endpoint code within your source code. This way, you can have a v1 and v2 endpoint which re-use common code at a lower-level service layer. This is something you don't need to do from the get-go. You can wait until v2 of the API to start separating things out.
  3. Automated testing of each build against existing API versions (and whatever new version you are building, but regression testing is the key point I am making).
  4. Forcing app updates, or at least tracking usage by app version, can allow you to remove/cleanup any code supporting legacy versions.

I am working on a similar project, creating a new REST API for a new mobile app. I am partitioning the URL space by version, so https://api.blahblahblah/v1.0/resource.

For the moment, I have my business logic built right into the code that accepts the HTTP requests because there is no other use for such logic. However, when I need to make a new version, I will refactor the v1 API code to separate anything not v1-specific into a more re-usable module which can then be re-used.

Depending on how structurally different your versions are, you may need some redundancies to keep your API's separated. For example, maybe you need a general UserEntity object to represent information about a user from your database, but then need a UserV1Resource and UserV2Resource object for the separate versions with adapters or some other design pattern to mediate the different types which get serialized to JSON or XML.

By having automated API tests, I am free to do any of that refactoring as I need, separating as I go, knowing that the moment I break any backward compatibility, my tests will scream at me.

A nice benefit of the API only being consumed by our mobile app for the time being is that we only need to worry about compatibility with the supported app versions. If we can make sure our end users are updating their app regularly, we'll be able to remove older versions, which helps minimize our technical debt.

like image 134
Brandon Avatar answered Oct 25 '22 19:10

Brandon