Nova/ProposalForAPIMicroVersions

Micro-versioning for Nova API
This is an evolution of the plan described here: https://etherpad.openstack.org/p/juno-nova-v3-api

The basic idea is:
 * make v2.1 replace v2
 * ensure older clients never get broken
 * but allow new clients to discover what new parameters they can send
 * allow new clients to request more information from newer APIs
 * do this all per extension, now everything is an extension

Major vs Minor Versions
Each extension gets a version

The basic plan:
 * client uses accepts headers to request specific version of API
 * version applies to each extension (or URL end point, but there can be aliases), not the complete API
 * no matched header, we reply with first stable version of extension (i.e. the v2.1 API, what was v3 changes would become the second stable version of that API extension)
 * ideally don't break any of: http://semver.org/
 * bump the major version if its backwards incompatible
 * every odd minor version is experimental, and .0 is not used, to save any confusion, so X.2 is the first stable version.
 * all changes are released as experimental before becoming stable
 * next stable version should be identical to previous experimental version, if changes are made, needs another release as experimental
 * need to support all stable versions for ever
 * only keep the last experimental version of any API, and only for two releases (i.e. delete release following the stable version is released)

This means v2.1, would report as v1.2, the first stable version, and v3 would be the micro version v2.2 of each extension

Open questions:
 * what do we consider as breaking changes
 * should client request just the major version, given minor is backwards compatible?
 * still report minor version so client can work out what requests are supported
 * URLs : how to deal with changes, probably just add alias URLs
 * Should we remove the version number in the URL, given its meaningless?
 * I think that should be our aim long term

Discovering extensions
First clients need to be able to find out what versions are avaiable.

In a cross project session, there was talk of adopting json-home to discover what urls and document types are available:
 * http://tools.ietf.org/id/draft-nottingham-json-home-03.txt

But we basically need to list:
 * all extensions (or better, all URL end points)
 * all available versions
 * json schema for request and response for each version

Implementation notes
Given the current v2.1 prototype, we can do something like this:
 * Ideally the code outputs the latest version (i.e. the current stable, or experimental version)
 * the transform logic is then able to re-write the new version back to the previous versions that are supported
 * so the code ouputs what would have been called v3, but is now micro version v2.1,

API wide microversion alternative (very rough outline)
Note: This is just a rough sketch of what I think has been suggested for a microversion that would be apply across the API (not an endorsement and could be a misinterpretation but just trying for now to map something out for comparison)

The basic idea:
 * A single monotonically incrementing microversion which applies across the API
 * eg 201, 202, 203
 * With each version increment the new API could contain a potentially backwards compatible or incompatible change
 * But 203 would have all the changes that 201 would contain
 * Clients would send an Accepts header specifying the range of the microversioned API that they are willing to deal with the server
 * Server would respond with the version range that they can comply with (which may or may not be within the range requested)
 * Client would then need to talk the version of the API that is acceptable to the server
 * or give up and upgrade the client?
 * extension versioning is either not relevant (because of the microversions), or could be left to indicate "experimental"
 * I think we'd still have json schema based API discovery as discussed

Extending global to major / minor versions and experimental versions
You can expand the above to a single global version that also describes the backwards or non-backwards compatibility of the change:
 * v2.1 becomes global microversion of v 1.2
 * v3 becomes a global microverson of v2.2 (because of backwards incompatible changes).
 * backwards compatible changes just rev the minor version
 * odd minor versions are considered "experimental" and likely to be changed in-incompatible ways and dropped without any notice