10

In a HATEOAS API links are returned which represent possible state transitions. A conforming client should just be retrieving and following those links, but if a non-conforming client is constructing URIs rather than following the supplied links what would be the most appropriate status code/response to return?

  • 400 would work, together with some information in the response body - this is what we're currently doing
  • 403 I guess would be wrong, as it implies that the request could never work - but potentially the link may be available in the future
  • 404 sounds plausible - at this point in time the resource doesn't exist

What do people think? I know that conditional requests can handle requests based on stale responses (resulting in e.g. 412s), but this is a slightly different situation.

Update:

OK, I see now that the correct response for these types of invalid operations would be a 404. How about where the syntax of a request is correct, it's going to a valid resource but it's somehow violating a business rule. Here's a couple of contrived examples:

  1. Let's say the client can provide two numbers which must be within 20% of each other, but otherwise could be any number.
  2. Let's say the client can provide a number which goes through some calculation the result of which indicates that the original number provided was incorrect.

Is 400 is the correct response for these?

1

2 Answers 2

6

If there's a chance that the links will exist in the future, both 400 Bad Request and 403 Forbidden would be incorrect: their relevant sections in RFC 2616 both have instructions that the client SHOULD NOT repeat the request. The difference between the two is that, in the case of 400 Bad Request, the server did not understand what the client was trying to do, whereas with 403 Forbidden the server did understand the request, but is refusing to fulfill it (ever).

If you want to indicate to the client that the request was understood, but you just won't handle it at the time of the request (but make no claim about handling it in the future), 404 Not Found would be the most appropriate response to send.

If you want to indicate to the client that request was understood, but the request does not follow predetermined rules or guidelines (like your example of a client not providing two numbers within 20% of each other), you want to use 409 Conflict, which is intended to indicate to the client that the request needs to be fixed in order to be handled properly.

You should separate good faith non-conformity from bad-faith non-conformity, though. If you're trying to protect your application from requests by a bad actor, they're almost certainly not going to care what response code you send: they'll just keep constructing URLs until they hit something they like.

2
  • OK, I think that gets to the heart of the question. I've expanded on it a little to cover a wider range of invalid operations - presumably for these 400 is the correct response?
    – FinnNk
    Mar 29, 2012 at 14:16
  • @FinnNk No, 400 Bad Request is only when the server can't understand what the client was trying to do at all. If it understood the request but the content of the request is invalid, you want to respond with 409 Conflict.
    – user8
    Mar 30, 2012 at 2:17
2

These codes follow the standard set by the HTTP rfc.

According to the Status Code Definitions section:

  • 400 Bad Request

The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.

  • 403 Forbidden

The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.

  • 404 Not Found

The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.

In your case, if the URI constructed doesn't lead anywhere I think it would be appropriate to return 404.

And if the URI is valid but the data passed (like a json doc) is broken, then you should return 400.

EDIT:

Answering the OP comment: I think the system should return 400 when the syntax and also the meaning of the data are broken.

4
  • By broken, in the context of a REST API, do you just mean syntax or does it also include the meaning of the data as well? See expanded question for more detail.
    – FinnNk
    Mar 29, 2012 at 14:17
  • Both cases should return 400, in my humble opinion. Mar 29, 2012 at 14:32
  • I've accepted your answer, but could you move your comment into the answer body? Cheers.
    – FinnNk
    Mar 29, 2012 at 14:35
  • On re-reading the HTTP rfc, Mark's further response makes a lot of sense, so I've switched the accepted answer. I have to say that it was a combination of both your answers which deepened my understanding here.
    – FinnNk
    Mar 30, 2012 at 20:57

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.