Author here. Unsurprisingly, we did have a lot of internet debate about how the version should be specified (header or path or query param) and we landed on using headers. But, to be completely honest, we didn’t find super strong arguments for any option, so it was just something where we had to be opinionated.
A strong argument is different from a strong opinion. Sounds like there are lots of people who feel strongly but none of them can put up a strong argument showing why one is better than the other.
Simplicity is a pretty strong argument in my mind. This whole thread has been full of arguments against. Not sure how we settle on if they are strong enough.
It seems not strong enough for Microsoft. But that’s why I was surprised as being a not very useful hassle would seem to be a big reason not to do it that way.
Cynically, I fear this method allows lots more versions and lots more breaking changes so get ready for stuff that could have been backwards compatible now just be a breaking change with a new version.
> Simplicity is a pretty strong argument in my mind.
But the URL version inly wins that argument if you ignore all the issues.
Github clearly wants to iterate their REST API faster and feels constrained, the URL method would mean either the entire API versions over quickly with almost but not quite copy pastes, or endpoints get versioned individually and you’re simultaneously hitting /3/foo and /42/bar with little rhyme or reason.
Things get confusing when you retrieve an entity via /6/ then update it via /4/.
For end users the api should be effectively versionless (i.e backwards compatible in all possible cases).
Most api consumers don’t care if fields are added or new methods added they are not using, thus they don’t care much about the version unless upgrading. Removing things or changing behaviour should be very rare and have a very good justification.
Short version: I do initial research against APIs using web browsers a LOT, including on my phone, and headers are really inconvenient for that.
In case you can't see DEAD comments, there's one here that talks about this too (and isn't offensive about it, so I imagine the account is DEAD for some other reason): https://news.ycombinator.com/item?id=33781215
I think the version should only be in the URL if you intend to support that URL forever.
I am of the opinion URLs are a promise the document will be available until the end of time. I don’t want to break the internet with 404s.
Since the only promise here is for the API to exist for 2 years when depreciated, then I think using a header is appropriate.
Query param doesn’t make sense either as it is often used as input data into the document at the URL. The document schema depends on the API version, so query params become a chicken/egg scenario
Surely, impact to API consumers was considered in changing to a header based approach. What if a company is using an API proxy like Apigee and now has to go through a change control process to incorporate a new custom header on outbound requests? If the 2 options for passing versioning ended up as a toss up, what arguments for a header based design outweighed the negative impacts to consumers?
One thing is not obvious to me: would the header accept any date and use that as a tie-breaker, or would the header only accept “version” dates?
Let’s say I start coding against the API today, can I just set the header to “today” and github will dereference that to the nearest preceding version, or do I have to look up and set the header for each endpoint?
IME it’s common to have a “broker” which handles all calls to the API in order to do common ore and post processing, having to look up and specify versions for each call sites would be frustrating, as well as the risk of different calls using different versions.
I went through this debate recently also and also ended up realizing there was no clear cut winner, but we did end up coming down on the same method of using headers. But oddly I get anxiety when I see other APIs that have gone for a different choice! Also considered that maybe could do all 3, or header || query parameter (which we may still do).