Hey guys!

tl;dr -- We need to get API versioning right. I'm proposing we use major 
versions in Accept/Content-Type headers.

In order for OpenStack to be successful, we need rock solid APIs. That means 
having something  stable that fully exposes the necessary functionality of the 
underlying service. In the case of the Compute API, I think we're fairly well 
off in terms of functionality. However, in order to achieve stability, we still 
need to get a few things right. I wanted to look at the Compute API first, as 
that's what I'm most involved in on a daily basis. What I've been concentrating 
on specifically is versioning. 

There are several aspects of API versioning that must be considered:

Numbering
- Major, minor, bugfix?

Backwards Compatibility
- At what level do you support backwards compatibility, if at all?

Communication
- Version in URI, mimetypes, or both?

Versions Collection
- Provide a complete list of supported versions?

Unsupported Versions
- What do you do when a request is made with an unsupported version?

Defaults
- Allow requests without explicit versions?

Scope
- Do versions apply to the complete API or to subsections? ...or both?


In order to help answer these questions, I looked at how some other popular 
service APIs are designed:

Twitter [1]
- Major version only
- Exposed in URI

Netflix [2]
- Major and minor versions
- Supports 1.0, 1.5, 2.0 (unclear how backwards-compatibile these are)
- Allows users to supply 'v' query param to specify version
- Defaults to 1.0

GitHub [3]
- Major versions only 
- Backwards compatability not guaranteed and documented where broken
- v2 supports version in uri
- v3 supports version in Accept header (application/vnd.github.v3+json)
- No version implies latest

Facebook
- No real versioning, just different service endpoints (currently 
differentiated by subdomains)
- legacy REST api wasn't versioned [4], and was replaced with unversioned Graph 
API [5]

Amazon EC2 [6]
- One implied major versions
- Timestamped feature releases (minor versions)
- Indicate version with query param
- Assume latest, since it will always be backwards compatibile

Sun Cloud API [7]
- No version in URI
- Allow user to send X-YYYYY-Specification-Version header to indicate what 
version they are speaking
- Root resource communicates its underlying implementation version and 
supported specification version(s)


So there obviously isn't one clear way to version a RESTful API. Not every API 
is created equal, and therefore doesn't need the same capabilities in its 
versioning mechanism. At this point, it is important to determine what 
specifically the Compute API needs:

- Our versioning mechanism should not hinder progress within the underlying 
implementation
- We need to be able to iterate on the design of our API without being tied down
- It needs to be simple to use from the point of view of API developers AND 
language bindings authors

With those goals in mind, I would like to propose we adopt the following 
mechanism:

- Use only major versions
- Allow backwards incompatibility between major versions
- Expose version of response in Content-Type header 
(application/vnd.openstack.compute.v3+json)
- Form request with version in Accept/Content-Type headers
- If no version is provided in request, default to stable
- If an unsupported version is requested, provide a 300 Multiple Choices 
response w/ list of available versioned mimetypes
- Provide a mechanism that can communicate all supported mimetypes (versions)

I would love to hear your feedback on this proposal, however, I'm not really 
looking to get into a fight about what's more RESTful ;) I know we already have 
several (slightly different) versioning mechanisms in place, but this is 
something that can't be wrong. There's still a lot to figure out here, but I 
think this is a good subset that we can reach an agreement on. In order for 
OpenStack to be successful, we need to get these foundation pieces right!

Brian Waldon (bcwaldon)

[1] https://dev.twitter.com/docs
[2] http://developer.netflix.com/docs/REST_API_Conventions
[3] http://developer.github.com/v3/
[4] http://developers.facebook.com/docs/reference/rest/
[5] http://developers.facebook.com/docs/reference/api/
[6] http://aws.amazon.com/documentation/ec2/
[7] http://kenai.com/projects/suncloudapis/pages/Home
_______________________________________________
Mailing list: https://launchpad.net/~openstack
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openstack
More help   : https://help.launchpad.net/ListHelp

Reply via email to