VersionDiscovery

Summary
Each service should advertise the API versions exposed by the service and the endpoint from where that service can be accessed. The purpose of this document is to standardize the format for these responses.

Version discovery is the only part of a service's API that is not itself versioned and so migrating existing services exactly to it is not always possible. This guide is intended as a best practice and should be followed strictly by new services. Existing services should follow this guide wherever possible and try to move towards this goal.

This document is intended primarily as a guide for the server side, some sections may contains notes about deprecated behaviour that is still allowed but it does not go into all the quirks for all the services that would be required to implement a version discovery parser that works for everyone.

Individual Version Entry
An API version is exposed as a series of attributes:

{       "id": "--id--", "status": "--status--", "media-types": [ {               "base": "--base--", "type": "--type--" }       ],        "links": [ {               "href": "--url--", "rel": "--rel--" }       ]    }

Individual version base URLs (eg at "http://localhost:5000/v3") will return a version object under the key of "version" with a status of 200 OK. Discovery endpoints should not be access controlled however this has occurred in the past and should be expected by anyone attempting to read them.

e.g.

Status: 200 OK   { "version": { "id": "3.0", "status": "stable", "updated": "2013-03-06T00:00:00Z", "media-types": [ {                   "base": "application/json", "type": "application/vnd.openstack.identity-v3+json" },               {                    "base": "application/xml", "type": "application/vnd.openstack.identity-v3+xml" }           ],            "links": [ {                   "href": ".", "rel": "self" }           ]        }    }

id
This is a required field

The id is the version identifier of an API endpoint. id is specified as a string in the format "{major}.{minor}.{patch}" for example "2.1.5". A patch version is optional and is considered 0 if not provided. Id versions follow semantic versioning and thus backwards compatibility is implied by a version numbering with the same major version and higher minor version number. For example an advertised version of "2.3" will maintain compatibility with of its calls with versions "2.0", "2.1", and "2.2" as well as all included patch versions.

Because of this compatibility only the most recent version need be provided to indicate compatibility with previous minor versions.

For compatibility purposes a version number may be proceeded by the letter "v". This should not be supported by future versions and should be completely ignored when parsing, so a retrieved id of "v3.2" is exactly the same as an id of "3.2.0". New projects should not use the "v".

status
This is a required field

The status reflects the state of the endpoint on the service. The following table presents endpoints in the order in which they should be prioritized. Stable defines whether the API is undergoing changes, e.g. if the API version is still under development.

updated
An ISO8601 formatted timestamp indicating the last update of this version status or number. This is updated when a new version is available or the status of the endpoint changes. It does not require changing on every API update to an unstable endpoint.

media-types
The formats in which this API is exposed. It is provided in a list of objects consisting of:


 * base - The basic mime type of the endpoint, eg "application/json"
 * type - A detailed specific application mime type, eg "application/vnd.openstack.volume+json;version=1"

links
''This is a required field and a rel of self link must be present. Each link object must contain at least a rel and href element.''

links is specified as a list of objects containing:


 * rel - The type of link being referenced. Supported `rel` types are:
 * self - The base URL for this version.
 * describedby - Documentation of this version of the api.


 * type - The mime type that is available at the specified link. This is generally used only in conjunction with the describedby link type and describes the type of documentation. eg "application/pdf"


 * href - A link to the base endpoint of the API. This is specified in normal href syntax, in that it supports:
 * absolute URLs, eg  'http://service/' 
 * relative URLs, eg  '/compute'  or  'compute' . This extends to allowing path traversal using the  '.'  and  '..'  paths.

Relative links should be preferred here unless the service exists on a different host or protocol. This means that the typical self  link when requesting a versioned endpoint (eg  '/v3' ) is going to simply be '.'.

A difference to the standard href linking syntax is that all urls provided by the href element are read to be folder elements. Eg If a request to  'http://service/prefix'  returned an endpoint of  'v1'  then the endpoint is deemed to be at 'http://service/prefix/v1/' as if the request was sent to  'http://service/prefix/'  and the endpoint returned was  'v1/'  (note the trailing slashes). This is intended to allow some leeway in configuration for operators and maintain backwards compatability and not an indication that trailing slashes should be removed from the link.

Root Discovery
The base entry point to a service will expose a list of versions keyed under the `versions` key. The information in each version information should be exactly the same as what is provided by each versioned endpoint (with the obvious exception that relative links will need to be relative to the current URL).

The return status code should be 200 OK. Discovery endpoints should not be access controlled.

Because greater minor versions include all smaller minor versions individually minor versions should not be included but considered available by other services.

eg.

Status: 300 {       "versions": [ {               "status": "CURRENT", "updated": "2013-03-06T00:00:00Z", "media-types": [ {                       "base": "application/json", "type": "application/vnd.openstack.identity-v3+json" },                   {                        "base": "application/xml", "type": "application/vnd.openstack.identity-v3+xml" }               ],                "id": "3.0", "links": [ {                       "href": "/v3/", "rel": "self" }               ]            },            {                "status": "SUPPORTED", "updated": "2013-03-06T00:00:00Z", "media-types": [ {                       "base": "application/json", "type": "application/vnd.openstack.identity-v2.0+json" },                   {                        "base": "application/xml", "type": "application/vnd.openstack.identity-v2.0+xml" }               ],                "id": "2.0", "links": [ {                       "href": "/v2/", "rel": "self" },                   {                        "href": "http://docs.openstack.org/api/openstack-identity-service/2.0/content/", "type": "text/html", "rel": "describedby" },                   {                        "href": "http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf", "type": "application/pdf", "rel": "describedby" }               ]            }        ]    }

By convention an endpoint version will be mounted under the subpath /v{major} eg /v3 as shown above, however this is not required so long as the URLs available from discovery are correct.