
As an expansion of the guidelines around microversions, add guidelines around how services should expose Version Discovery documents. This includes recommendations for putting unversioned endpoints into the catalog. It also includes a completely new thought, so feel free to punch me in the head - that versioned discovery documents should include a collections rel link to allow clients to get from the versioned to the universioned document without having to do URL manipulation. If we can get that in, it should serve as a bridge for those clouds that are still putting versioned endpoints into the catalog for a while for backwards compat reasons. Two related follow-up patches are in-work. One that adds a copy of the consuming-discovery document with all of the extra effort in support of clouds and services that to not implement these guidelines removed, so a "perfect future state" is easy to read. The other is a document recommending a global cloud "profile" that greatly reduces the API burden on clients consuming this information. Change-Id: Id8160048dfffc1ada32ce876a65b02fb7a02306e
6.2 KiB
Microversion Specification
This topic document serves to provide guidance on how to work with microversions in OpenStack REST APIs.
Microversions enables the ability to introduce API changes while being able to allow clients to discover those changes. According to negotiations with servers, clients adjust their behavior to work with server correctly.
Versioning
Versioning of the API should be single monotonic counter taking the form X.Y following these conventions:
- X should only be changed if a significant backwards incompatible API
change is made which affects the API as whole. That is, something that
is only very rarely incremented. X should be changed in the following
cases.
- A number of endpoints get replaced by others
- Drastic changes in API consumer workflow
- Y should be changed when you make any change to the API. Note that this includes semantic changes which may not affect the input or output formats or even originate in the API code layer. We are not distinguishing between backwards compatible and backwards incompatible changes in the versioning system. It will however be made clear in the documentation as to what is a backwards compatible change and what is a backwards incompatible one.
Note
Note that these versions numbers do not follow the rules of Semantic Versioning.
There are minimum and maximum versions which are used to describe what the server can understand. The minimum and maximum versions are the oldest and most recent versions supported. So clients can specify different version in the supporting range for each API call on the same server. The minimum version can be increased when supporting old clients is too great a burden. Increasing the minimum version means breaking the old clients, this happens very rarely also.
Services expose information about their minimum and maximum supported
microversion range as part of version-discovery
.
Each version includes all the changes since minimum version was introduced. It is not possible to request the feature introduced at microversion X.Y without accepting all the changes before X.Y in the same request. For example, you cannot request the feature which was introduced at microversion 2.100 without backwards incompatible changes which were introduced in microversion 2.99 and earlier.
Client Interaction
A client specifies the version of the API they want via the following approach, a new header:
OpenStack-API-Version: [SERVICE_TYPE] [VERSION_STRING]
For example, Keystone will use the header:
OpenStack-API-Version: identity 2.114
This conceptually acts like the accept header.
Clients should expect the following behavior from the server:
- If the OpenStack-API-Version header is not provided, act as if the minimum supported version was specified.
- If the OpenStack-API-Version header is sent, but the value does not match the current service, act as if the minimum supported version was specified.
- If the OpenStack-API-Version header is sent, the service type
matches, and the version takes the form of a version string respond with
the API at the indicated version. If the version is outside the range of
versions supported and is not the string
latest
(as described below), return 406 Not Acceptable, and a response body including the supported minimum and maximum versions. - The value of
OpenStack-API-Version
header is[SERVICE_TYPE] [VERSION_STRING]
. The VERSION_STRING must match "^([1-9]d*).([1-9]d*|0)$". If the VERSION_STRING doesn't match the regex pattern, return a 400 Bad Request with an error response body that conforms to the errors guidelineerrors
. - If OpenStack-API-Version header is sent, the service type matches,
and the version is set to the special keyword
latest
behave as if maximum version was specified.
Warning
The latest
value is mostly meant for integration testing
and would be dangerous to rely on in client code since microversions are
not following semver and therefore
backward compatibility is not guaranteed. Clients should always require
a specific microversions but limit what is acceptable to the version
range that it understands at the time.
Two extra headers are always returned in the response:
OpenStack-API-Version: [SERVICE_TYPE] version_number
Vary: OpenStack-API-Version
The first header specifies the version number of the API which was executed. An example:
OpenStack-API-Version: compute 2.22
The Vary
header is used as a hint to caching proxies and
user agents that the response is also dependent on the
OpenStack-API-Version and not just the body and query parameters. See
7231#section-7.1.4
for
details.
Note
Servers must be prepared to deal with multiple OpenStack-API-Version
headers. This could happen when a client designed to address multiple
services always sends the headers it thinks it needs. Most Python
frameworks will handle this by setting the value of the header to the
values of all matching headers, joined by a ',' (comma). For example
compute 2.11,identity 2.114
.
Note
A Python library called microversion-parse is available to help with server-side processing of microversion headers, both the new style described in this document and previous forms.
When the requested version is out of range for the server, the server returns status code 406 Not Acceptable along with a response body.
The error response body conforms to the errors guideline errors
with two additional
properties as described in the json-schema below:
{
"max_version": {
"type": "string", "pattern": "^([1-9]\d*)\.([1-9]\d*|0)$"
},
"min_version": {
"type": "string", "pattern": "^([1-9]\d*)\.([1-9]\d*|0)$"
}
}
An example HTTP Header response:
HTTP/1.1 406 Not Acceptable
Openstack-API-Version: compute 5.3
Vary: OpenStack-API-Version
An example errors body response:
microversion-errors-example.json