Hacker News new | ask | show | jobs
by icebraining 5461 days ago
>he says version numbers in the url are bad but doesn't say why.

Because according to the spec, each resource is named by a single URL, so two URLs name two different resources. But if you put version numbers in the URL, you might end up with http://example.org/v1/rubyrescue and http://example.org/v2/rubyrescue, which according to the spec are two different users but in reality they're the same.

>also a v1 user really might not be the same as a v2 user

In what cases should the users be tied to the API version? I can't think of any.

3 comments

"Because according to the spec, each resource is named by a single URL, so two URLs name two different resources."

I don't think this is technically correct. For instance, you might have a blog with a post at /blog/2011/07/03/why-i-love-rest and you might have /blog/current represent the same resource until you post something new. This seems like a valid case in which two different URIs name the same resource.

If you are versioning the resources themselves I think the version in the URI is perfectly fine. In reality this is almost never the case and people mainly use the version in the URI to designate different versions of the representation. This is bad since it ties the URI to the representation which is a big no-no.

Hmm, I think that those URLs are still different resources; one is 'the current post' and the other is 'the post named "Why I love REST"'. I would do a 302 from the latter to the former.
Ah, fair enough. They are indeed two different resources. Would you have a problem if I returned the actual representation rather than a 302?
I don't have a 'problem' with it, this is just conceptual talk. But I'd still do it for SEO reasons.

If Google fetched /blog/current as containing the "Why I love REST" post and showed it to me, and the when I clicked the link I got "Why I think turtles are awesome", I'd be annoyed. A 302 fixes that in a more clean way than entries in robots.txt or similar tricks.

EDIT: Apparently Google messes that up and often associates the content with the source URL and not the destination URL. Disregard the previous paragraph.

Seems like people are mixing up ways of providing web services with overall site design and url friendliness......
good point, but the point of a restful resource is that the url represents a resource, but then w/accept header versioning, i now need two pieces of data, one of which isn't visible, to properly represent and retrieve a resource.

I guess my point is that if i have to pick, i'd rather occasionally have two request urls with a minor version difference that are actually the same resource than two urls that appear to be the same resource but are not because one was requested with a header that affects the returned data.

You're confusing resource with representation. An URL is a resource, but if the representation of that is a JSON document or a picture of him/her, that's up to the server. Just because an header affects the representation of a resource, doesn't mean they're different resources.
actually that's a good example that makes my point. if i said to you - well if you want to retrieve a person's user information, just GET /users/1 with Accept: text/json. If you want their photo, just GET /users/1 with Accept: image/jpeg - philosophically, i'm not violating the 'rules of REST' but it feels wrong to me.
Sure, I would create a "User's photo" resource too and link it from /users/1, but that's because a user's photo can be a new resource, so it can have its own URL.
What do you mean by visible? Visible in the URL bar of a browser? The headers are all there in the request, for all to see.
yes i'm thinking more pragmatically. From an API perspective the header is part of the request but given that the human-readability of urls is a feature of http, it just somehow feels wrong to me to modify the response based on a request header.
I think most developers don't see that as a problem.

We modify the response all the time based on headers like User-Agent, Referer, If-Unmodified-Since, Accept-Language and others, so using Accept for versioning isn't really that strange.

User-Agent: modifying based on this is a Bad Thing

Referer, If-Unmodified-Since: these only decide if you respond or don't or error, they don't generally change a successful transfer

Accept-Language: I was under the impression that this was buggy and not well-supported, but it is a good example in theory

The response is changed all the type depending on the value of the Cookie header.
iiuc, two resources can contain the same value, (http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch...) so you're not constrained by the number of identifiers with which you can reference a single entity. furthermore, it's debatable whether the versioned identifier hierarchy adheres to the principles of HATEOAS and discoverability, so practicality probably rules when implementing such an API.