-
Notifications
You must be signed in to change notification settings - Fork 9
Versioning
Versioning is a pain. It forces clients to keep some state and is very prone to error (e.g.: what happens when the version changes in the middle of the client's session?). Instead, we propose that we version things just like programming languages do. We:
- Think really hard about what our base URL's look like so changing them is highly unlikely (think of /xml/store as part of the syntax of a language)
- Major new features in the API add new endpoints. Old clients don't know about these new endpoints and can continue to use the old ones blissfully (to a point)
- Enhancements to existing endpoints are done with new parameters
Perhaps it's easiest to look at an example of an upgrade to the API in order to get a sense of how things would look. One such upgrade would be the addition of transformers.
If version information is added into the request, what would the requests look like for storing a new named transform? Would they fall under the 1.0 version? Probably not. Perhaps they'd go under 1.1 or something like that. If this is the only change to the API as a whole, would the entire API also get upgraded to v1.1? Essentially what we're asking here is this: are all the endpoints upgraded to a new version unanimously, or individually? Individually seems like a mess to the user, so we'll say that even the endpoints that didn't change have their version number increased. This makes putting the version at the front of the URL logical. So adding a new transform would look like:
/v1.1/manage/transformer/foo
Using the transformer when fetching a document looks like:
/v1.1/xml/store/bar.xml?applyTransform=foo
This is all fine, except that it makes things kind of painful on our end as we'd have to do a fair amount of checking to make sure that a given endpoint is really accessible under that version.
What it also means is that we'd have to support multiple versions of the API, something that we feel is a requirement. So we propose that adding the transformer feature be done exactly as it was. Adding a new transformer looks like:
/manage/transformer/foo
Using the transformer when fetching a document looks like:
/xml/store/bar.xml?applyTransform=foo
If a new client calls an old server, they can either get an error back saying that applyTransform isn't supported or the parameter can just be ignored. Naturally old clients can still make their requests as they were.
When removing functionality, first it should be deprecated for many versions. Usage of deprecated features can log warnings on the server. Down the road, the feature can be removed and a 404 (or something reasonable) can be returned.
Essentially, adding the version in the URL just expands the URL space. This gives us extreme flexibility with what changes we can make to the API. But such big changes are likely very painful for those using the API so we shouldn't want to make them in the first place.
So to summarize, if we're confident in the structure of our endpoints we see no reason why an explicit version needs to be specified at request time. If we lack confidence, are just throwing things against the wall and want to support the things that we threw against the wall, adding a version number might be a good idea. If we don't want to support our past mistakes for a while, a version number is of no value.
Feel free to poke holes in our logic :).