tags:

views:

2284

answers:

6

Should the representation(html, xml, json) returned by a RESTful web service be determined by the url or by the Accept HTTP header?

+11  A: 

Both are valid. Quote from xml.com:

A resource may have more than one representation. There are four frequently used ways of delivering the correct resource representation to consumers:

  1. Server-driven negotiation. The service provider determines the right representation from prior knowledge of its clients or uses the information provided in HTTP headers like Accept, Accept-Charset, Accept-Encoding, Accept-Language, and User-Agent. The drawback of this approach is that the server may not have the best knowledge about what a client really wants.
  2. Client-driven negotiation. A client initiates a request to a server. The server returns a list of available of representations. The client then selects the representation it wants and sends a second request to the server. The drawback is that a client needs to send two requests.
  3. Proxy-driven negotiation. A client initiates a request to a server through a proxy. The proxy passes the request to the server and obtains a list of representations. The proxy selects one representation according to preferences set by the client and returns the representation back to the client.
  4. URI-specified representation. A client specifies the representation it wants in the URI query string.
Darin Dimitrov
A: 

Since very many RESTful URLs do not have an extension, you should/must base on Content-Type

edit: I don't mean this to sound as harsh as it does, more that you're going to have to pay attention to content-type and won't always be able to refer to extension

annakata
The concept of "RESTful URLs" is nonexistent, or misguided at best.
Wahnfrieden
That's utter nonsense. Tell me that http://foo.com/getuser.php?id=99 is RESTful. If it isn't then a set of !RESTful URLs exists and by definition a RESTful set must also. And that's a trivial example, there are plenty of URLs and site designs which can and cannot be said to map to a RESTful system.
annakata
What? It helps if URIs are readable, and it's good to follow HTTP conventions for URI naming, but it's an orthogonal issue to REST. REST doesn't care what it looks like. The server manages its URI space however it likes, since the client shouldn't know anything about how URIs are constructed - it simply receives them through hypertext. So while your example URI isn't very nice, it doesn't have to do with being RESTful or not.
Wahnfrieden
You're missing my point. See where it says "get"? That's the problem.
annakata
@annakata You're simply wrong - while including 'get' in the URI may be a hint that the developer doesn't know what he's doing and did not follow REST constraints, the name of the URI itself is not a violation of any REST constraint. It's merely an indication that something may be wrong, but you can name URIs however you like and still be RESTful.
Wahnfrieden
Well this is productive. I'd say we should agree to differ since I don't believe we even have consensus about the terms of this discussion, but no doubt I'd be simply wrong about that too.
annakata
Just go read Fielding's dissertation and you'll find nothing about how URIs are supposed to be named or what they should look like.
Wahnfrieden
I'm not engaging in this comment tennis any more: post your own answer if you wish, otherwise this merely becomes trolling. And please don't cite bibles as authority when the world keeps evolving.
annakata
This is RPC:foo.com/getuser.php?id=99This is REST:GET foo.com/user.php?id=99(it's using HTTP method 'GET')The SAME URL can now be used with different HTTP methods:DELETE foo.com/user.php?id=99
opyate
@opyate: exactly, and if this distinction exists then by definition REST and !REST exists. Glad this was obvious to someone!
annakata
+4  A: 

Use the Accept header if provided, URI as a failover.

chaos
+2  A: 

This is a non-question.

Accept depends on conneg. Conneg will let the client decide what media type they accept through the Accept: header. The response will then be in that format, together with a Vary: Accept header.

On the other hand, it's also possible and perfectly valid to expose your resource as /resource.json and /resource.xml.

The ideal is to implement both: /resource (generic uri that supports conneg) /resource.xml /resource.json

the conneg'd version returned by /resource can simply redirect to the correct uri based on the negotiated media type. Alternatively, the correct representation can be returned from the generic uri, and use Content-Location to specify the sepcific representation that was returned.

serialseb
Wrong, according to REST. Each RESOURCE should only have a single URI - not each representation of that resource.
Wahnfrieden
You seem to take a very specific and biaised view of the notion of resource. Any thing that is useful enough to be addressable individually can be assigned a URI. If you need to make the distinction between two formats, you can "promote" them as resources.See W3C note on generic URIs and Roy's comments about what content-type negotiation should be used for: whenever and only when the distinction between the two media types is not significant.
serialseb
@Wahnfrieden Can you point us to the official source for your position on this? I've seen lots of discussion around this but never seen any concrete decision been written down.
Darrel Miller
+1  A: 

Since you're mentioning a RESTful web service and not any web service, I would strongly go for what is supported by underlying standard - HTTP 1.1 and its content negotiation that relies on Accept HTTP header.

As I've explained in my answer to Can I change the headers of the HTTP request send by the browser, address (URI) and representation are two distinct pillars of a RESTful design and they do not need to be mixed. One should not abuse URI for embedding acceptable representations when there's Accept header.

Only if your web application is potentially run and used in an environment where's some HTTP header filtering involved by intermediate nodes, then you should support URI-based content negotiation. Truth be told, such intrusive or improperly functioning proxies should be replaced if anyhow possible and feasible.

Cheers!
Shonzilla

Shonzilla
+3  A: 

There are problems with using content type... I discussed this on my blog http://shouldersofgiants.co.uk/Blog and finally settled on including the representation in the URI as suggested in RESTful Web Services by Richardson and Ruby

+1 the Richardson and Ruby book.
opyate