15

I am writing a Rest API and am wondering how best to handle supporting the different versions. By this I don't mean how to define a URI as V2 or V3, but rather how to structure the code given that it'd need to:

  • Support multiple versions at the same time, eg. V1 & V2 & V3 URIs must be live at the same time. I would retire V1 when say V4 comes in in order to constrain the amount supported at any one time.
  • Avoid as much code duplication as possible
  • Make it easy to add non-breaking changes to a version, without it impacting on other versions

It would seem that there are few approaches that could be taken:

  • Use Git to control the versions, with a branch for the different versions (and old versions essentially having no new development work done on it). This would mean no code duplication as only the latest version is in the code, but previous versions would need to work with the new version of the DB until they are retired.

  • Duplicate code so that each version is handled in the same application and has a totally separate code path, but this would mean a lot of duplication

  • Re-use a lot of code across the versions, but this would make it harder to maintain as changing one version is more likely to impact a previous version

Is there any best practice to deal with this problem as all options seem to have their own problems?

  • 1
    If you specify the version number in the URL (e.g. myserver/api/3.1.4/user/get), you can pass the version number into whatever function you call so you can localize version-specific behavior without sharing too much code. – James McLeod Mar 12 '14 at 2:39
5

Do this:

Re-use a lot of code across the versions, but this would make it harder to maintain as changing one version is more likely to impact a previous version

but don't break the previous versions.

You should have tests that verify that all supported versions are working correctly. If you don't have those tests, then you should first create them to cover any code you are changing.

2

A combination of using GIT release branches (or fork each version into a separate repository) to support and maintain old API versions and possibly have some re-usable code that can be shared as a dependency, like a commons library, is most likely the way to go. So each API version would be a separately deployable artifact. This allows flexibility so that, for example, API V1 can depend on commons V1, while APIs V2,V3,V4 can depend on commons V2. This would be the easiest and cleanest from a development perspective as your code base doesn't multiply with each new version, instead every version is isolated into it's own project/code base and is only concerned with itself.

Another reason to deploy separate artifacts is that there may be cross cutting concerns like a security mechanism, or frameworks/libraries like your dependency injection framework that could change in newer versions of the API and would create a lot of difficulty in supporting older APIs if they all live in the same code base (and Classloader at runtime, if it's Java).

Every approach, whether its a branch per version or monolithic duplicated code base, is always going to have the issue of a common integration point (like the DB, or a distributed cache schema) needing to change. Older version APIs may require some kind of maintenance to work with those changes, or the introduction of some other tools (like database views) to help compatibility. This may be an unavoidable difficulty depending on the nature of your changes.

0

I don't know how different the results are from your API versions are, but you could have a compatibility layer in the middle which can toggle between the versions and fill in gaps or translate data.

That being said - it usually never works out one to one - so a switch or state machine type design has helped me with this problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.