Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What HTTP status code should server return if client request can't be fulfilled at the moment because of some business logic?

Tags:

rest

http

api

I have a chat application that works in browsers and uses REST API backend. It has following business logic rules:

  1. a user can start chat session with any other users

  2. a user can be in one and only one chat session at the time

  3. if userA and userB have started a chat session and the session is currently active, then if userC tries to start chat session with either userA or userB server should prevent that and return some kind of error to userC

My question is what would be appropriate HTTP status code for this error that userC should receive?

This is not fault of the client so 4xx codes don't seem appropriate.

This is not server error so 5xx codes also don't seem appropriate.

I will send response body with additional JSON info message of why request failed but what would be appropriate HTTP status code that would satisfy RESTful principles?

like image 656
mlst Avatar asked Dec 22 '22 18:12

mlst


2 Answers

409 sounds the most appropriate here. 409 is often used in cases where a request is otherwise valid, but cannot be fulfilled because of the current state of the server/some other resource. If that 'other state' changes, the request could be valid again.

I wrote a bit more about 409 Conflict here: https://evertpot.com/http/409-confict

like image 95
Evert Avatar answered Dec 25 '22 12:12

Evert


An important thing to recognize is that status codes, like headers, are meta data that belong to the transporting documents over a network domain. The audience for a status code isn't just your bespoke client, but also all of the general purpose components participating in the message exchange.

My question is what would be appropriate HTTP status code for this error that userC should receive?

The first thing to work through is the appropriate class of status code to use. For unsafe requests, the primary question to ask is "did this request change the representation of the resource?" If it did, then you want to think about using a 2xx status code, because you will want the general purpose components to be using cache invalidation to evict the now out-of-date representations in their caches. If the resource didn't change state, then you want to be reviewing the 4xx status code.

In either case, you can get a sense for the possibilities by reviewing the Status Code Registry, deciding which descriptions seem likely, then reviewing the authoritative reference to see if the semantics match what you are looking for.

More often than not, you can cheat and jump immediately to RFC 7231 -- the most familiar status codes are defined by the HTTP standard.

This is not fault of the client so 4xx codes don't seem appropriate.

It's probably the correct choice, though. 5xx is "I wanted to do what you asked, but I couldn't" is unlikely to be the right choice.

403 Forbidden is a pretty good option that says "I understood what you wanted, but I'm not going to do it. It's most commonly associated with a credentials problem, but the standard explicitly allows us to use this code elsewhere

a request might be forbidden for reasons unrelated to the credentials.

409 Conflict is a reasonable candidate.

The good news is that, aside from the human semantics, there isn't actually a lot of difference in how general purpose candidates handle these two status codes. For instance, they have exactly the same default caching behaviors.

HTTP does have a standardized treatment of conditional requests; "apply this change to the resource only if the specified predicate is true". That, in effect, gives you a compare and swap operation - you tag your request with metadata indicating which version of a resource you are looking at locally.

Conditional requests have their own special error code to handle a request that is out of date: 412 Precondition Failed. There's also a 428 Precondition Required status code if a request is missing a predicate and you want to insist. The client would be expected to include an appropriate precondition header to proceed.

As noted by Andrei Dragotoniu, status codes aren't intended to describe your domain behaviors. So you sometimes need to consider that 2xx is appropriate, because the server did what you asked, even though what you asked didn't have the outcome you hoped for.

Imagine, for example, a game on the web; you make a legal move, and the result of your move is that you lose the game. What status code should be used? Probably a 200 in that case - the server's state machine moved from playing the game to losing the game, and that's a perfectly legit outcome for a correctly handled HTTP request.

I don't guess that applies in your case; but you have more information to make that judgment.

like image 39
VoiceOfUnreason Avatar answered Dec 25 '22 12:12

VoiceOfUnreason