[Openstack] OpenStack API Versioning Conventions

Mark Nottingham mnot at mnot.net
Wed Oct 12 02:52:55 UTC 2011


It might help to talk about *what* might change, and what kinds of versioning are available.

E.g.,
  * Changing the methods supported by a resource, or their semantics (in the case of POST)
  * Changing the URI query parameters available to a resource
  * Changing the range of formats that a resource consumes / produces
  * Changes within the individual formats themselves
  * Changing the HTTP headers produced / consumed
  * Adding / deleting resources to the overall interface

In each of these cases, there are backwards-compatible changes; e.g., supporting a new method or query parameter, adding a new format, adding a new member to a JSON object. Older clients can interoperate just fine, despite these changes, so NO change is necessary to any identifiers (URIs, media types, etc.), assuming that discovery is a separable problem, and debugging information can be made visible without being so intrusive.

There are also backwards-incompatible changes in each case; e.g., changing the meaning of POST on a resource, or the meaning of a URI query parameter, or removing support for a method / query parameter, or making substantial changes to the representation formats themselves.  All of these changes will, if made incorrectly, break old clients, and so they should be avoided where possible.

In cases where we absolutely need to make incompatible changes, we can introduce new URIs or new media types to accommodate it, whilst still supporting the "old" one.

The important thing here is that there isn't *one* versioning strategy that works for all sorts of changes; each type of change is individual.

George, when you say that we shouldn't have versions in URIs, I agree as an aspirational goal. I.e., we should strive to NEVER break old clients, and therefore the URIs should not change very quickly -- ideally, at all.

I do think, however, that we probably need a major version identifier in the URIs, to allow us to *once in a blue moon* wipe the slate clean and start a fresh API. That doesn't mean that we'd stop supporting the old API, of course; they'd have to run in parallel (for a sunset period, at a minimum, if not forever).

One technique we could use to reach that goal is to NOT bake URIs into the specifications, but rather have clients inspect the APIs to discover links to the various kinds of resources they want to use. This decouples the API from the URI space, and makes extensibility and versioning much easier -- but it does require a certain discipline on behalf of the clients, in that they have to first discover the URIs they want to interact with.

There are some downsides to this approach (e.g., it is more "chatty", and to be efficient, it requires client-side caching), but it might be worth discussing as at least a partial solution.

Cheers,


On 12/10/2011, at 1:54 AM, George Reese wrote:

> No, not at all.
> 
> The object is /servers/1234 regardless of the versioning of the API. It's an object that exists independent of your API and its version. A URI should represent a single, persistent reference to that object.
> 
> The version is really an attribute of the content type you are accepting. It tells you what kind of content the client is expected to send to you and to receive from you. In particular, the structure of the data representing the persistent object.
> 
> /servers/1234 should always represent that 1 server. Forever. Unless the URI has changed, in which case a v1 client will respond with a 302 and a v2 client with a 404. A v1 client can then query /instances/1234 and get the version 1 xml or json. A v2 client querying /instances/1234 gets version 2 xml or json.
> 
> -George
> 
> On Oct 11, 2011, at 3:11 PM, Soren Hansen wrote:
> 
>> 2011/10/11 George Reese <george.reese at enstratus.com>:
>>> Versioning should not be included in the URI. It belongs in the headers. A URI should be a persistent reference to a resource. As such, versioning always breaks that persistent reference.
>> 
>> I don't follow. If the version is included in the URI, that's got to
>> be a more persistent reference to a resource than a URI whose
>> behaviour differs depending on a header that you have to include?
>> 
>> -- 
>> Soren Hansen        | http://linux2go.dk/
>> Ubuntu Developer    | http://www.ubuntu.com/
>> OpenStack Developer | http://www.openstack.org/
> 
> --
> George Reese - Chief Technology Officer, enStratus
> e: george.reese at enstratus.com    t: @GeorgeReese    p: +1.207.956.0217    f: +1.612.338.5041
> enStratus: Governance for Public, Private, and Hybrid Clouds - @enStratus - http://www.enstratus.com
> To schedule a meeting with me: http://tungle.me/GeorgeReese
> 
> _______________________________________________
> Mailing list: https://launchpad.net/~openstack
> Post to     : openstack at lists.launchpad.net
> Unsubscribe : https://launchpad.net/~openstack
> More help   : https://help.launchpad.net/ListHelp

--
Mark Nottingham   http://www.mnot.net/







More information about the Openstack mailing list