API Versioning - Orodan/Hilary GitHub Wiki

Considerations

Development Process

It's likely we'd just want to add functionality to the standard ctx to support versioning, with an attempt to avoid pushing versioning concerns down into internal APIs. We should strive to handle it all on layers where we give access to the request context.

A version utility that we add to the context could work in the following way:

ctx.version().is('<10.1'); ctx.version().is('>=10.4');

The concept of "latest version" should exist as default, and be backward compatible with current usage (e.g., /api/search instead of /api/v10.1/search; or alternatively no version head specified). Obviously as far as logic is concerned, when no version is specified, the context version is greater than everything, and smaller than nothing.

/api/ui/* endpoints should not be advertised as versioned as they are a 3akai-ux plugin for the back-end, not general back-end API services.

Conventions we should try and adhere to:

  • Where possible, try and make the "happy path" the one that adheres to the latest version, and the historical version is the special case
  • Avoid causing breaking changes in patch version increments
    • The need to do a version check on a patch version number (e.g., ctx.version().is('<10.1.3')) should be considered a red flag and caught on review
  • Version checks should be easily grep-able. If version 10.1 becomes obsolete, I should be able to do a couple greps to identify existence of special cases revolving around that version:
    • git grep "=10.1"
    • git grep "<10.2"
    • git grep ">10.0"
  • We should have an API that reports earliest supported version, though it may not be useful to enumerate all versions that have existed between the earliest supported version and the latest version
  • The file that communicates the "earliest supported version" should also be use-able by a linting utility that will help warn about the existence of conditional handling that we are free to fully deprecate

Testing

  • Our standard oae-rest client utility should be updated to take in an API version
  • In a perfect world, I think we should be able to checkout a tag of the code-base, and run the unit tests of past versions of the app against the most recent version of the app with an API version set
    • Such a process may wind up being too time-consuming to run before releases
  • It may suffice to, in situations where unit tests need to be changed for updated logic, we instead write targeted tests that ensure backward compatibility in those areas

Communicating Versioning to the API

  • Whatever is chosen should not complicate deployment procedures. It shouldn't require any changes to nginx.conf to regularly support new versions of the API, and it shouldn't require any dedicated servers
  • Some options:
    • We should investigate the use of Accept header parameters in express (e.g., Accept: application/json; version=10.4)
    • Something like Accept: application/vnd.oae.v10.4+json, while unfortunately ugly, may suffice in place of using a base URI
    • If express can easily allow us to convert /api/v10.1/... into /api/... and resume regular route processing with version metadata in context, that would be a less ideal option