HATEOAS REST API – Handling ‘Invalid Operation’ Status Code

api-designhateoasrest

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?

Best Answer

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.