[Openstack] API Versioning and Extensibility

Mark Nottingham mnot at mnot.net
Thu Oct 27 04:19:14 UTC 2011


On 27/10/2011, at 5:19 AM, Bryan Taylor wrote:

> On 10/24/2011 11:20 PM, Mark Nottingham wrote: 
>> tl;dr
> Much omitted, since it's long... I agree strongly with 98% of what you are saying.
> 
> I'll focus on the variants here. I'd rather just get rid of them.

I think there's a discussion to be had, but it's not a yes or no thing.


>> GET /servers.v1.json
> vs
>> http://api.example.com/v1/foo
> 
> I agree with you that the latter violates some RESTful ideals, but so does the former. Whether the "v1" comes with dots or slashes or at the root or leaf of the hierarchy doesn't really change the fact that you are polluting your resource namespace with representation specific information. The same goes for .json: internet standard vs openstack representation doesn't matter - it's still representation information. 

I'm not interested in conforming to "RESTful ideals" for their own sake, so no worries there.

My problem with indicating the media type versioning in the root of the URI is that /v1/ style URIs typically indicate the versioning of the *whole* API, not just the media types being used. They're orthogonal concerns, and should be (i.e., I can introduce a new media type without bumping the whole API). As I mentioned before, overloading /v1/ like this ties your hands if you want to rearrange the API down the road -- so this isn't just convention, it's a convention for a reason.

Also, from a purely social standpoint, people understand indications of format variations being expressed as filename conventions.

That's not the main issue here, though.


> You could argue the /v1 doesn't belong at the top of the resource tree, but this removes ambiguity about the ordering. eg: /servers.json.v1 vs /servers.v1.json.

There's no ambiguity; the server owns the URLs.

> To be truly RESTful at the level of the Fielding article (which I actually think is the best description of HATEOAS there is) you shouldn't have these variants at all.  I worry about us trying to put lipstick on the pig -- all these variants are a crummy compromise to work around broken browsers that do allow changing the accepts header. 

It's perfectly legitimate to link to a resource that has only one representation, such as having /foo.html to allow people to specifically refer to the HTML version of the /foo resource. That's effectively agent-driven negotiation, and it's just as valid (RESTful, if you will) as server-driven negotiation. Nothing that Roy has said contradicts that, because a core principle of REST (if we really want to go there) is that important things have identity, and that links are what drive things (agent-driven negotiation is just linking, really).

The problem comes in when you do strange things like PUT a JSON representation to /foo.html -- that just doesn't make sense. I'm kind of wary of the current approach in the API, because as far as I see, it tries to do a programmatic equivalency between server-driven and agent-driven content negotiation, when they're two different things; the corner cases are going to catch you out (as above).

However, I don't have strong feelings about one vs. the other; each is appropriate in different circumstances.


> I floated the idea a while back that we get rid of variants altogether and instead use an HTML representation to offer the user a choice of how to view the information that includes <pre> elements with JSON and XML formatted text. It could also have a nice human readable representation so that users could directly navigate around in the browser. Remember that the only use case justifying variants are human developers who want to see what the JSON or XML will look like.
> If we do this, then we have GET /server/1234 and everything is clean. Jorge pointed out one slight problem with this: <pre> can only display textual representations. So no pdfs or excel spreadsheets without conneg. If we could live with this, getting rid of the variants altogether seems like a win.


Why not just return HTML that uses XHR to pull in the JSON and XML on-demand, when the Accept header prefers HTML? 

WRT PDFs and Excel -- I think you mean that we can't use server-driven conneg on them? I think that's reasonable. Like I said above, we need to have the right tools for the right jobs, and if some URLs are format-locked / format-specfic, that's entirely sensible, as long as we have a good reason for it. 

All of that said, an incompatible change in format should result in a new URL; e.g., if you want to fundamentally change the representation of servers, it should be something like:

http://api.example.com/servers/{server_id}  <-- old server format
http://api.example.com/srv/{server_id} <-- new server format
http://api.example.com/servers/{server_id}.v2 <-- ... or this

You'd still define a new media type for the new format; you just wouldn't rely on server-driven negotiation to find it. Anything that requires a backwards-incompatible change is going to make it a fundamentally different resource anyway, I think. Using the approach to versioning and extensibility in the other thread, this would also necessitate a different link relation type.

Yes, I realise that this moves away from having a single URI for every "thing" in the system, but again, it's OK to give different views of things different URIs, as long as you explain the relationships between them with links. 

Cheers,


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







More information about the Openstack mailing list