I used both strategies that you mentioned. Of these two, I prefer the second approach, being simpler in cases of use that support it. That is, if the need for versioning is simple, then go to simpler software:
- A small number of changes, low complexity of changes or a schedule with a low frequency of changes.
- Changes that are largely orthogonal to the rest of the code base: a public API can exist peacefully with the rest of the stack without requiring “excessive” (for any definition of this term that you decide to accept), branching in the code
I was not fortunate enough to remove obsolete versions using this model:
- Good coverage for testing meant that tearing down the retired API and its associated support code guaranteed no (well, minimal) regressions
- A good naming strategy (package names with API versions or somewhat ugly versions of the API in method names) made it easier to find the appropriate code
- Extensive problems are more complicated; modifications to the underlying backend systems to support multiple APIs must be carefully weighed. At some point, the cost of a backend version (see the comment on “excessive” above) outweighs the advantage of a single code base.
The first approach is certainly simpler in terms of reducing conflict between existing versions, but the overhead of maintaining separate systems tends to outweigh the benefits of reducing version conflict. However, it was very easy to get into the new open API stack and start iterating in a separate API branch. Of course, the loss of generations appeared almost immediately, and the branches turned into a mess of mergers, combined conflict resolution and other similar entertainment.
The third approach is at the architectural level: use the Facade template option and draw your APIs on public framed versions that speak to the corresponding Facade instance, which in turn accesses the backend through its own set of APIs. Your Facade (I used the Adapter in my previous project) becomes its own package, self-sufficient and verifiable, and allows you to transfer front-end APIs independently of the backend and each other.
This will work if your versions of the API demonstrate the same resources, but with different structural representations, for example, in your name fullname / forename / surname. It gets a little more complicated if they start to rely on various backend-based calculations, for example, “My backend service returned incorrectly calculated compound percentages that were exposed in the open API v1. Our clients have already fixed this incorrect behavior. Therefore, I cannot update this calculation in the backend and applying it to version 2. Therefore, we now need to develop our percent calculation code. " Fortunately, they tend to be infrequent: in practice, RESTful API users prefer an accurate representation of resources over backward compatibility with error for errors, even among constant changes to a theoretically idempotent GET resource.
I will be interested to hear your final decision.
Palpatim May 26 '15 at 18:31 2015-05-26 18:31
source share