REST HTTP Response Code when 3rd party ressource became unaviable - rest

in one scenario i got some data from client. With this client i want to start a booking.
Now it could be possible that the booking can't be done. For example when the ressource is sold out und became unaviable.
What would be a good reponse code for this?
I tested some apis and found there is often 500, 400,404 as a result.
A 500 looks just weired for me.
Also 400 is strange, because the api didn't do any wrong.
404 doesn't feel right, because the ressource is there, it just can't be bought right now.
Any advice on best practice?

One of the possible http error codes to use for this is 410: Gone.
The explanation for this code:
Indicates that the resource requested is no longer available and will
not be available again. This should be used when a resource has been
intentionally removed and the resource should be purged. Upon
receiving a 410 status code, the client should not request the
resource again in the future. Clients such as search engines should
remove the resource from their indices. Most use cases do not require
clients and search engines to purge the resource, and a "404 Not
Found" may be used instead.

Related

Should I throw a 400 or 500 service error for business logic fail?

I'm working on a music media library that allows users to share music in their library but only if they marked as shareable.
In the backend I'm checking if the music file is shareable like so
if(file.shareable) share
else throw 500 or 400?
To me this is a 400 bad request because the the user is trying to do something that the business does not allow.
Is this the corret way?
4xx indicates a bad request -- i.e. "don't try re-requesting".
5xx indicates that the server had a problem, i.e. "give us a minute, and try again later."
So if it's business logic, that would be a 400 level error, i.e. don't re-request.
You should use 4xx codes for any client error that prevents the server from returning a useful response. This includes requests that violates business rules. The point is to indicate to the client that the request is invalid, and potentially include steps the client can take to fix the situation.
Use 5xx codes if the server encounters an internal problem that prevents it from doing its work. Maybe the database or a necessary external service is down, or there's a programming error somewhere. Maybe the server is just too busy right now. Not much the client can do to fix that other than try again later.
Basically:
4xx: Your fault.
5xx: My fault.

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

I have a chat application that works in browsers and uses REST API backend. It has following business logic rules:
a user can start chat session with any other users
a user can be in one and only one chat session at the time
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?
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
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.
First of all what you use is all upto you. There is no silver bullet to decide, you can think of the error code that you feel suits the usecase.
If I was writing this application, I would prefer to return 400 for this. Initiating a chat with a user which is already chatting with someone is a client's intention. If application cannot satisfy this request I would consider to return 400. And in the error message you can say that user is already in chat session with someone else.
5XX is a server side error which should not apply here because the server is still running fine. So I wouldn't use that
Some people will even return 200 and have a error field which tells the request actually failed. So all such things ends up to developer preferences.
The status code that seems more appropariate is 409 Conflict it shows exactly that the server won't accept the request because it is busy or doing something else.
for more info see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

HTTP error code when server cannot find a user-given external resource

Our image board allows users to upload images by copy-pasting URLs. A client app sends a POST request to our API with an image URL given in the request body. Our web service receives the POST request and handles it by downloading the image from the given URL by using a server-side HTTP client (request in our case).
In successful case, the service finds the image, downloads it, and stores it to the server. The service returns HTTP 200 to the client.
Now, what if the image cannot be found? What if the download attempt results in HTTP 404? What HTTP error code should we use to response to the client?
HTTP 400 Bad Request is not applicable because the request was well-formed and all parameters were valid.
HTTP 404 Not Found is not applicable because the request URL was found and served although the image URL was not.
HTTP 502 Bad Gateway does not feel right either because there is nothing wrong with our server or the upstream server (the server of the source image). The user just happened to type in an image URL that does not exist.
Any experience on the matter? Which error code is the most correct?
First of all you should decide if this is a client error (4xx) or server error (5xx). From what you describe, it feels more like a client error. The client has requested the creation of a resource from another resource (the image URL) which does not exist.
There is no perfect match for this scenario, although one could make a case for each of the 2 following response codes:
HTTP 409 Conflict: From the RFC:
The request could not be completed due to a conflict with the current
state of the target resource. This code is used in situations where
the user might be able to resolve the conflict and resubmit the
request...
This applies to your case if you consider the target resource to be in a bad state (image not found). If someone provides an image at the specified URL, that effectively transitions your resource to a valid state.
This is also a good match because, as the RFC states, this code implies the user might be able to resolve the conflict (in your case the user would correct this by posting the image to the specified URL).
HTTP 424 Failed Dependency: From the RFC:
The 424 (Failed Dependency) status code means that the method could
not be performed on the resource because the requested action depended
on another action and that action failed...
This applies to your case in that "the requested action depended on another action and that action failed". The dependent action is the posting of an image to the other URL. What you have described is a case where that dependent action either failed or did not happen (which could also be called a failure).
Since the API determines on something that is not available, its service is unavailable as well.
The status code 503: Service Unavailable is the best fit for your situation.
According to the RFC description:
The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response.
Alternatively, if your API supports a way of communicating errors (e.g. to tell the user that the information he submitted is incorrect) you may be able to use this method to tell the user that the external resource is unavailable. This might be a little friendlier and might avoid some error raises on the user's side.
Since the client app sends POST requests to your API server the response codes should be generated according to the received server in your case this is your API server.
If the server has received correct information from the client app and server determines the request as valid, it should return apropriate code with proper JSON or header based error messages.
http error codes were conceived assuming that all pages possibly served were stored locally, one way or another.
Your scenario does not match that assumption and it should therefore not come as a surprise that you don't find codes that fit your bill properly.
Your "not found" scenario is in fact an application error and you should notify your user of the situation by providing an error message on the form where he entered the URL (or return a fully dedicated error page or some such). Or choose an http error nonetheless and accept the notion that it will be a poor fit no matter what.
Now, what if the image cannot be found? What if the download attempt results in HTTP 404? What HTTP error code should we use to response to the client?
The main thing to keep in mind: you are trying to fool the client into thinking that you are a web site - just a dumb document store which might respond to some content editing messages.
For the client, the primary means of communication is the body of the response. See RFC 7231
Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition.
The status code is meta-data: aimed at giving the generic components participating in the exchange a chance to know what is going on (examples: the web browser doesn't need to know what page you are asking for to recognize a redirection response returned by the server, the web browser asking for credentials when it receives a 401 unauthorized response, web caches invalidating entries, or not, depending on the status code returned by the response).
HTTP 400 Bad Request is not applicable because the request was well-formed and all parameters were valid.
Yes, that's exactly right.
I would probably use 500 Internal Server Error, on the grounds that there's nothing wrong with the _document that the server received, the problems are all involved in the side effects of the server's implementation.
A different approach you might consider: 202 Accepted. Roughly translated "I got your message, I understood your message, and I'll get around to it later." If you don't need the side effects to be synchronous, you can defer judgment. That allows you to do things like applying a retry strategy.
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.
"I'll get to it later; if you want to know how it is going, go ask him -->"
Because 202 is a non-error status code, its effect on caches is different from those of a 4xx or 5xx. If you are already thinking ahead about caching, you'll want to the implications of that in mind.

API: what HTTP status code to use for multiple items found error?

Suppose there is a lookup API endpoint. A response can be successful (200), not found (404), ... and in my case more than one item found is an error. Which HTTP status code can describe more than one item found error the best?
Suppose there is a lookup API endpoint. A response can be successful (200), not found (404), ... and in my case more than one item found is an error. Which HTTP status code can describe more than one item found error the best?
The server fully understands the request, but can't deliver a representation that meets its part of the contract.
So the right error code is going to be in the 5xx range.
The 5xx (Server Error) class of status code indicates that the server is aware that it has erred or is incapable of performing the requested method.
If none of the specialized 5xx error codes fits, you should use 500
The 500 (Internal Server Error) status code indicates that the server encountered an unexpected condition that prevented it from fulfilling the request.
Michael Kropat did a good job of enumerating the options in Stop Making It Hard. He makes this interesting observation about 502
I can tell you we would have saved hours upon hours of debugging time if only we had distinguished 502 Bad Gateway (an upstream problem) instead of confusing it with 500 Internal Server Error.
The modern definition of "gateway" can be found in RFC 7230 section 2.3 (Intermediaries).
A "gateway" (a.k.a. "reverse proxy") is an intermediary that acts as an origin server for the outbound connection but translates received requests and forwards them inbound to another server or servers. Gateways are often used to encapsulate legacy or untrusted information services, to improve server performance through "accelerator" caching, and to enable partitioning or load balancing of HTTP services across multiple machines.
All HTTP requirements applicable to an origin server also apply to the outbound communication of a gateway. A gateway communicates with inbound servers using any protocol that it desires, including private extensions to HTTP that are outside the scope of this specification.
Very very roughly, 500 is "my bad", where 502/504 points a finger somewhere else.
what error code would you use for my case?
Based on what you have described, 500. That's appropriate for "my representation of this resource is corrupt."
The reasonable alternative is 502, which is appropriate for "the upstream representation of this resource is corrupt".
In either case, the audience for the error is internal (the client can't do anything to correct the problem. Your support team probably can't do anything useful with the distinction between the status codes). You could just as reasonably argue that the fact that the problem is upstream is an implementation detail of no interest to clients (so 500 everything). Alternatively, you could argue that your API is a gateway that translates received requests and forwards them inbound to another server, and therefore the status code should because the problem is in your store, not in your api.
So it comes down to things like "when tracking the number of errors we have in the api, do we want to distinguish this sort of issue from an exception being thrown internally"?
Authoritative guidance seems to be lacking; choose a method, document your justification, and ship.
That's an interesting problem. If it's an API call for a lookup and you get multiple results back, I'm actually expecting a 200 code with an results array.
But if the request itself is wrongfully formatted, so that it's not clear what it is the client is asking for, you could send a 400 bad request http status code.
Also have a look at the 207 multi-status code, as this might actually closer what you're looking for. Could you maybe provide request and response examples?

Correct HTTP status code for a not satisfiable REST request

I currently develop a task queue with a RESTful API.
In order to handle a task, a worker has to create a lease.
PUT .../leases
If the task queue has tasks available, this will succeed, a lease will be created and the server responds with status 201.
I am unsure how to handle this case when no tasks are available. It is not possible to create a lease, when no tasks are available. Which HTTP status code would be appropriate for this case?
204 No Content - The client hasn't made anything wrong, but there is no data.
400 Bad Request - This is imho not applicable, as it means "the request could not be understood by the server", which is not the case
In the meantime I thought that this approach might not be ideal. Either I use 503, as recommended of Brian and also backed by a passage of REST in practice, or I change the whole process.
I was thinking of leases which could be created tentatively. That means
PUT to /leases
Either create a lease, assign a task and respond with 201 or create a tentative lease and respond with 202
Tentative leases will stay for some time. If tasks gets available, they are assigned to the tentative leases. If there is no task for a specific period of time, the lease gets deleted and the server will respond with 410
The client should then start again with 1.
Since the resource is controlled by the server and there's nothing the client can do to influence the outcome, a 500-range code would be most appropriate.
503 - Service Unavailable sounds right to me. It implies that the server has not got enough resources available to meet the needs of the request. You should probably also return a meaningful error in the body of the response to make it explicitly clear that it failed because no leases/tasks were available, but that might not be the case sometime in the future.
404 - Not Found could be used. Wikipedia summarizes it as:
The requested resource could not be found but may be available again in the future. Subsequent requests by the client are permissible.
404 almost works, but I think of it as the resource you are dealing with and you are doing a PUT to create a resource. Of course it doesn't exist that's why you are creating it.
I would agree with your first thought on the 400 Bad Request in a narrow sense of the definition. But if you broaden the definition to include anything that could go wrong with the request then it would fit your situation and I think it's acceptable to do just that. For example we send a 400 back if the request didn't meet the schema we were expecting and if there are validation errors on the resource. For our service if we can programmatic determine that this is a bad request we send back a 400.
For your service the creation of a lease when no tasks are available constitutes a bad request, and you can send the 400 with text explaining what the problems is. I think the 400 was meant for a broader definition then what you are holding it to.
I don't think the 500's work because they are more unhandled stuff, and this is a case you can handle and provide informational responses to.
Hope this helps.
IIS sends a 405 Method Not Allowed if I try to use an unsupported method (ie PUT when it expects a GET). And it sends a 404 Not Found if the endpoint doesn't exist at all.