17

While designing a RESTful API we came across the problem of how to access different versions of the "same object". Let us say a page object is identified by a unique key and accessed by GET /api/page/pagekey. It can be updated by sending PUT /api/page/pagekey and an appropriate document in the body.

Now our system keeps track of old versions of the page, that we also want to access via the API. Let us assume that an older version of the document is version 1. There seem to be at least two ways to design the API to access this particular version of the page:

  1. GET /api/page/pagekey/1
  2. GET /api/page/pagekey?version=1

The first variant renders the particular version as its own resource; the second variant gives the existing resource an optional version context.

  • Is variant (1) or (2) a better solution? Or is there an even better way to do it?
  • In variant (1) a request for a version number that does not exist e.g. /api/page/pagekey/7 could trigger a HTTP 404 Not Found, which is quit handy. Would this also be a valid status response when considering variant (2), where we only change the context "version" of the existing resource, that would without the version parameter return a HTTP 200 Ok response?
Community
  • 1
  • 1
Herr Jemine
  • 171
  • 1
  • 4
  • I'm curious - what did you end up going with? – bryanmac Oct 05 '12 at 12:33
  • It seems we will go for the second variant (parameter) even though I would personally prefer the first, as you would. One of the reasons is that our front end stuff reported that backbone js has difficulties dealing with the first variant. – Herr Jemine Oct 08 '12 at 15:35
  • makes sense - considering the consumers of the API id definately important :) – bryanmac Oct 10 '12 at 01:49

2 Answers2

10

Each resource url should be a permalink to identify that resource.

GET /api/page/{id}/{rev}

That certainly is a permalink to a specific version of the resource. So, that's fine. But note that the permalink does not require the content to be the same over time:

GET /api/page/{id}

That will return the latest revision which is fine and will change contents over time. To expand on that, you can even have temporal resources like this and be RESTful:

GET /api/page/latest 

But, /api/page/{id}?version={rev} will also work and doesn't break any RESTful concepts.

I think the /{id}/{rev} is a bit purer since it specifically identifies that resource in the addressable url and feels a little more correct than putting making it a param. The reason is the params should be modifiers on how to retrieve the contents and not necessarily mutate the distinct resource you're retrieving. In your case, since each version is distinct, it seems more appropriate to distinctly address the resource. But, even that one doesn't break any RESTful url rules or concepts and if you asked 10 folks you might get a different answer :)

Either way, you should likely ensure the temporal resource /api/page/{id} returns the latest revision.

murrekatt
  • 5,961
  • 5
  • 39
  • 63
bryanmac
  • 38,941
  • 11
  • 91
  • 99
0

Almost by definition, REST will have no notion of "same object". If you need this in your protocol, then you'll need to have some kind of "identifier". As simple as that ;)

A URL parameter is one obvious way to go. "/1" or "?version=1" are certainly two good alternatives - which you choose is just a matter of preference (as well as a question of how much "other stuff" you might also want).

Either way, you're still going to have to cope with "version not found" kinds of errors, and recover gracefully.

IMHO...

paulsm4
  • 114,292
  • 17
  • 138
  • 190