From a RESTful point of view, I think it perfectly alright to handle both representations the same. Consider a software with several versions you want to download, the latest one being 3.8. So if you want to get the latest version, you could address it with both GET /software/version/latest.zip
and GET /software/version/3.8.zip
until there comes a newer version. So two different links point to the same resource.
I like to imagine pagination pretty much the same. On the first page there are always the latest articles. So if no page
-parameter is provided, you could simply imply it's 1.
The approach with the rel
attribute goes in a slightly different direction. It's a creation of Google to better handle the problem with duplicate content and is primarily considered to be used in order to distinguish between a "main" page and pagination-pages. Here's how to use it:
//first page:
<link rel="next" href="http://www.foo.com/foo?page=2" />
//second page:
<link rel="prev" href="http://www.foo.com/foo?page=1" />
<link rel="next" href="http://www.foo.com/foo?page=3" />
//third and last page:
<link rel="prev" href="http://www.foo.com/foo?page=2" />
So from a SEO point of view it's a good idea (and recommended by Google) to use those elements. They also go perfectly with the resource-orientated idea of REST and the hypermedia representation of the resources.
Choosing one of your suggestions, I think the 303 See Other
is the right way to go. It was intended to be used for this kind of purposes and is a good way to canonicalize your resources. You can make them available through many URIs, but have one "real" URI for a representation (like the software with different versions).
According to the specification, the response should look something like this:
303 See Other
Location: http:www.foo.com/foo?page=1
<a href="http:www.foo.com/foo?page=1">http:www.foo.com/foo?page=1</a>
So you provide a Location-header with the "real" representation, and the body should contain a hypertext document linking to the new URI. Note that according to the specification the client is expected to send a GET request to the value of Location, but it doesn't have to.
//EDIT as answer to your comment (yep, it's really bad practice to claim something without proving it :-) - my bad!):
Google presented the rel="next"
and rel="prev"
attributes in September 2011 on the Official Webmaster Central Blog. They can be used additionally to (or in some cases instead of) the rel="canonical"
tag.
Under those links you can find the differences between them explained:
rel="next"
and rel="prev"
link elements are "to indicate the relationship between component URLs in a paginated series"
- the
rel="canonical"
"allows you to publicly specify your preferred version of a URL"
So there is a slight difference between them. So you can break down your problem to a canonical issue: There are several URLs pointing to the same resource (/foo
and foo?page=1
but you have a preferred version of the URL (foo?page=1
). So now there are a few options for a RESTful approach:
- If there is no
page
-parameter given in the query, use a default value (e.g. 1) when processing it. I think in this specific case it is OK to use a default value even though you point it out as bad practice.
- Respond with 303 See Other providing the preferred URL in the Location-header (as described above). I think a 3xx-response is the best (and most likely RESTfully intended) way to deal with duplicate/canonical content.
- Respond with 400 Bad Request in case you want to force the client to provide a
page
-parameter (as explained by zzzzBov in his answer). Note that this response does not have something like a Location header (as assumed in your question), so the explanation why the request failed and/or the correct URL (if given) must go to the entity-body of the response. Also, note that according to the specification this response is commonly used when the client submits a bad/malformed representation (! not URL !) along with a PUT
or POST
request. So keep in mind that this also might be a little ambiguous for the client.
Personally, I don't think your suggestion to respond with 405 Method Not Allowed is a good idea. According to the specification, you must provide an Allow-header listing the allowed methods. But what methods could be allowed on this resource? I can only think of POST
. But if you do not want the client to POST
to it either, you could also respond with 403 Forbidden with an explanation why it is forbidden, or 404 Not Found if you do not want to tell why it is forbidden. So it might be a little ambiguous, too (in my opinion).
Using link
-elements with the mentioned rel
-attributes as you propose in your question is not essentially 'RESTful' because it's only hypermedia which is settled in the representation of the resource. But your problem (as far as I understand it) is that you want to decide how to respond to a specific request and which representation to serve. But still it's not absolutely pointless:
You can consider the whole SEO issue as a side effect of using rel="next/prev/canonical"
, but keep in mind that they also create connectedness (as the quality of having links) which is one of the characteristics of REST (see Roy Fielding's dissertation).
If you want to dive into RESTful Web Services (which is totally worth it) I recommend reading the book RESTful Web Services by Leonard Richardson and Sam Ruby.