7

I have been in the process of generating documentation for an upcoming project. One of the features of the data available in this project is that it will be revisioned (or at least large parts of it will be).

I came across the (as I understand it, very new) "Accept-Datetime" HTTP header. This looks absolutely perfect for enabling access to revisioned data using existing interfaces.

My question is this. Which return type should be used for:

  1. A date received that is before the initial data date (I am thinking maybe 404 with body error description)?
  2. Data that is requested using the header, but that does not support versioning (This is the really sticky one for me. Not sure whether an error, or just the normal data is better)

Edit: For the moment, in the second case, I am tentatively putting code 406 - Not Accepted

1 Answer 1

1

So, the mechanism described in (informational) RFC 7089 defines an extension to the content negotiation mechanism defined in the HTTP 1.1 spec. The officially supported content negotiation parameters today are:

  • Accept
  • Accept-Charset
  • Accept-Language
  • User-Agent

These headers are used to inform the server of the desire for a particular version of a resource (e.g. Accept-Language: de). The HTTP 1.1 spec defines what the server can do in response to an attempt to request a content type that it does not support. In this case, the server should respond with a 406 (Not Acceptable) response. Per the specification, the 406 response indicates:

The resource identified by the request is only capable of generating
response entities which have content characteristics not acceptable
according to the accept headers sent in the request.

Which is consistent with a user specifying that they want a particular point-in-time version of a resource but that version does not exist.

So, for your first question (query for date before the initial date), you should respond with a 406.

For your second question (what to do about un-versioned resources) you have two choices regarding the meaning of the state of your resource at the requested time.

If you consider un-versioned information to have no time dimension then you can decide that either it always succeeds or always fails (again with a 406).

Making the case for "always succeeds" you could contend that un-versioned data is valid for all time (if it's not versioned then it never changes) the system-defined assumption is that if the data ever existed, then it always existed since the beginning of your system universe. As an example, a request for an immutable property like UUID or serial number should (possibly) always succeed.

Making the case for "always fails with 406" you could claim that if the user specified a specific date then she expects a version of the information and since the resource being requested has no versions, the server cannot satisfy the request and therefore should generate an error response.

I would advocate the always fail approach.

A couple of things to note:

  1. RFC 7089 is informational and is not guaranteed to become part of the formal spec.

  2. You should consider adding a Vary header in your response to make sure that caching does the right thing with responses to time constrained queries.

  3. You could accomplish the same behavior without relying on RFC 7089 by working within the constraints of the current HTTP spec and using the generic Accept mechanism with a customized media-range. This would be custom stuff (not usually a good thing) but, RFC 7089 is not official either.

1
  • Absolutely fantastic answer. I moved from this particular project and company some time ago, but this is certainly one of those answers I will come back to reference in the future! Thanks so much
    – major-mann
    Dec 19, 2017 at 11:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.