Best practices for API backwards compatibility
api, backwards-compatibility
Solution
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.
Problem
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