Best practices for API backwards compatibility

Mark picture Mark · May 23, 2012 · Viewed 9.5k times · Source

I'm working on an iPhone/iPad/Android app which communicates with a JSON API.

The first release of the version of the app is complete, and now additional phases of development are taking place. In the additional phases, the app needs to integrate with a new version of the API and allow the user access to additional features such as new screens or modified behaviour within existing screens. The app does however need to be backwards with previous versions of the API.

What is the best practice for tackling such a requirement? I could of could do checks throughout the code:

if (APIVersion == 1) {

} else if (APIVersion == 2) {

} else if (APIVersion == ....) {

}...

But I'm concerned about the scalability of this approach. The factory method comes to mind but I'm not sure how far this would get me.

Thanks, Mark

Answer

wrygiel picture wrygiel · May 23, 2012

Release of a new API version is a very rare thing. Usually you can achieve backward-compatibility just by adding new optional parameters or new methods. For example, if you had method named search, but now you are dissatisfied with the way it works, you may deal with it in various ways:

  • If the change is simple you may add a new mode parameter which defaults to mode1 (so it's backward-compatible). If user supplies mode2 you detect it with a proper if condition as you proposed yourself. (Also, usually you can think of a better name than "mode".)

  • If the change is a big one, you may add a new search2 service which uses the new interface. Then you mark search method as deprecated (but still working and backward-compatible). Usually when you do this, you can refactor your code in such a way, that almost all of the logic is inside the search2 method, and your old search method calls search2 internally with modified parameters (and re-formats the results appropriately). If you do this properly, you won't ever need to change search method anymore. When you alter your tables etc. - you will only need to modify search2.

My point is, avoid releasing N+1-st version of an API. Such big release implies major changes in ALL of your methods, not just one. Many major APIs never released version 2 of their API, they still use version 1, just slightly modify portions of it, as in the example above.

If you are absolutely sure about releasing N+1-st version of you API, create new entry points for ALL of your methods. If you had a folder named services, create new one named services-v2. Refactor your services code so that it uses the most of services-v2. If you think it's overkill, then I think you don't need N+1-st version of your API yet.

BTW, do not confuse centralized APIs (like Google Maps) with distributed ones (like Android). Android releases new API versions all the time, because there are billions of Android servers (each Android device is one), and they all cannot be simply upgraded remotely by Google. The next version of Android is still backward-compatible with the previous one, the number is increased only to indicate new features. E.g. You can still run apps built for Android 3.0 on Android 7.0 (the user might get some extra warnings, but the app will run). Android-app developers use these numbers in order to describe "minimum requirements" for their apps. Whereas, centralized APIs usually increase their version number to indicate a major backward-incompatible change.