Search code examples
resthttphttp-status-codes

using HTTP Location header to indicate the location of a future resource


Following the REST Level 2 specification described in the Richardson maturity model by Martin Fowler a response to a POST request creating a resource looks something like this:

HTTP/1.1 201 Created
Location: slots/1234/appointment
[various headers]

<appointment>
  <slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/>
  <patient id = "jsmith"/>
</appointment>

I would like to follow this model but in my application when an endpoint is called to create a new resource it's added to a queue instead of created immediately and so I'm responding with a HTTP 202 instead of a 201.

I would also like to include a URL indicating the future location of the content which the user can GET once the queue is processed. Can I leverage the Location HTTP header to be used for this? Resulting in something like:

HTTP/1.1 202 Accepted
Location: slots/1234/appointment

on MSDN it states this regarding the Location header:

It only provides a meaning when served with a 3xx (redirection) or 201 (created) status response.

If that's the case what other standardised HTTP alternative is available for such a case?


Solution

  • RFC 7230:

    The status-code element is a 3-digit integer code describing the result of the server's attempt to understand and satisfy the client's corresponding request. The rest of the response message is to be interpreted in light of the semantics defined for that status code.

    So the meaning of the Location header is to be interpreted in light of the 202 Accepted semantics.

    The "Location" header field is used in some responses to refer to a specific resource in relation to the response. The type of relationship is defined by the combination of request method and status code semantics.

    For 201 (Created) responses, the Location value refers to the primary resource created by the request. For 3xx (Redirection) responses, the Location value refers to the preferred target resource for automatically redirecting the request.

    There isn't, that I can tell, any defined semantic meaning for Location in the context of a 202 Accepted, which is to say that general purpose components will not know how to interpret your intent.

    When we look at the semantics of 202 Accepted, we find:

    The representation sent with this response ought to describe the request's current status and point to (or embed) a status monitor that can provide the user with an estimate of when the request will be fulfilled.

    One might reasonably expect that the "resource in relation to" the 202 Accepted response would be the status monitor, rather than the eventual target of the POST operation. There's enough ambiguity there that I wouldn't try to use the Location mechanism.

    Web Linking is probably a better solution for your problem; it gives you a standardized way of communicating an arbitrary relationship between resources. You can review the registry to see if there is a registered relation that has the semantics that you need, or you can define your own extension relation.

    Hypertext media types will have their own mechanisms for describing link semantics (for example, the "rel" attribute in HTML). But there is also a header that you can use.

    Note: registered relations weren't handed down on tablets; you could go through the registration procedure to create a new registered relation that satisfies your use case. My guess is that getting some real experience with the semantics as an extension relation first will make the registration process smoother.