Why is error 410 a user error and not a server error? - rest

Why is error 410 considered a user error (4xx) and not a redirect (3xx) or a server error (5xx)?
I request a payload from a server, and the server returns a link. I copy the link and the link gives 410? It isn't my fault to verify the link actually exists on their server. But at the same time, from the server's point of view the error originated from me, as I accessed something that doesn't exist, similar to 404 where I access something that was never there.
Can anyone help me understand the decision behind this?
Code 410
"410 Gone" client error response code indicates that access to the target resource is no longer available at the origin server and that this condition is likely to be permanent.
If you don't know whether this condition is temporary or permanent, a 404 status code should be used instead.

Why is error 410 a user error and not a server error?
It's not a "user" error, it's a client error; but yeah, that's a lousy label. The labels reflect the client-server architectural constraint, but it might be better to use labels that point more directly at the contents of the request, rather than the client (or the user).
In practice, it's a client error for the same reason that 404 is a client error; it is specifically calling attention to the target resource of the HTTP request.
In the context of the web, it does make some (imperfect) sense - the client followed a broken link (which could be a consequence of the server's current representations, but might also come from following links in stale representations, following stale bookmarks, a spelling error in a representation provided by a different server, etc).

It's not a question of fault, it just means that the request should not be considered to ever work in the future (it shouldn't be retried). Whereas a server error (like a 5xx error) could be retried periodically and should eventually work sometime in the future since the request itself is considered valid.

Related

BadRequest vs NotFound when the resource is a sheet but the user required is not found

I'm just having a discussion here with my colleague regarding what is the best response to return when requesting a specific resource i.e. a datasheet for example, and the url is valid but part of the process when processing this datasheet is to get a specific user which may not be found.
I found this question on SO: Should a RESTful API return 400 or 404 when passed an invalid id
My understanding is that if the request is valid i.e. the url and the parameters pass to it, it should return a 404 (NotFound) if the user is not found.
But my colleague's point is that the datasheet is the resource and therefore since the user requested is not found, it should actually be considered as 400 (BadRequest)
Can someone clarify what it should actually be?
Thanks
Although BadRequest might make sense initially it does not fit the definition of a 400.
400: The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
Reserve a 400 for when the request is missing required fields, an incorrect data type was provided, etc.
In your case, it sounds like the user has made a valid request but that part of the data needed for completion is not found (I'm guessing this is a part of the Uri). This sounds a lot more like a 404, which is perfectly valid when something other than the specified resource is not found.
404: 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.
The specifics of what was not found can be expressed in the error code or the error message.

What HTTP code to return for a POST to a resource URI which depends on the responsiveness or accessibility of another related object?

I am performing a POST to a resource URI. But the success of this operation depends on the responsiveness or accessibility of another related object. If that object is not responsive or inaccessible, the operation needs to return failure. What HTTP code should I choose in this case?
I am currently brainstorming on the following codes, but could not arrive at the right one:
404 NOT FOUND - This represents "not found" for the resource URI, and not a related inaccessible entity.
412 PRECONDITION FAILED - Applicable only for conditional requests with one or more header fields indicating a precondition - I dont need to provide any.
I am not able to find or zero onto a specific HTTP code.
https://greenbytes.de/tech/webdav/rfc7231.html#status.409:
"6.5.8 409 Conflict
The 409 (Conflict) status code indicates that 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. The server SHOULD generate a payload that includes enough information for a user to recognize the source of the conflict."
Lets check the candidates:
404: always an option but as the same request will sometimes fail or success this will create a flickering behavior which is not what a client would expect when getting 404.
412: RFC 2616 says: "The precondition given in one or more of the request-header fields" - this is not the reason for the failure.
417: similar to 412: "The expectation given in an Expect request-header field could not be met by this server"
503: "The server is currently unable to handle the request due to a temporary overloading or maintenance of the server."
Nothing seems to be perfect but I would choose 503 as it represents the temporary problem best and guides the client to do a retry.
Picking the right status code is always tricky. If you return a status code like 404 for example, debugging can become derailed because someone may not be sure if it's because the URL actually doesn't exist or if it's because of some other reason internally.
Usually the caller only needs to know a few things:
Did the endpoint exist? If not, 404 NOT FOUND
Was my request properly formed and did it pass validation? If not, 400 BAD REQUEST
Was my request denied because of improper authentication? If not, 401 or 403 depending on the context (there is a subtle difference)
Did my request fail because of something out of my control? If so, 500 INTERNAL ERROR
Typically I try to separate the response from the service's logic. If you want to be more specific as to exactly what happened (in your example a dependency is not responsive), returning a bit of JSON that describes in more detail what the problem was is would be a more appropriate place for that as opposed to using the http status code to describe a specific error on the service side.
So in your case, I think 500 is the most appropriate. The caller just knows that something went wrong and there's nothing it can do about it, and it can handle that condition however it needs to. If the caller needs to know more about what happened, use a JSON response to convey that.
List of HTTP status codes
1xx Informational
2xx Success
3xx Redirection
4xx Client Error
5xx Server Error
Refer wiki :
103 Checkpoint
Used in the resumable requests proposal to resume aborted PUT or POST requests.
420 Method Failure (Spring Framework)
A deprecated response used by the Spring Framework when a method has failed.
420 Enhance Your Calm (Twitter)
Returned by version 1 of the Twitter Search and Trends API when the client is being rate limited; versions 1.1 and later use the 429 Too Many Requests response code instead.
450 Blocked by Windows Parental Controls (Microsoft)
A Microsoft extension. This error is given when Windows Parental Controls are turned on and are blocking access to the given webpage.
498 Invalid Token (Esri)
Returned by ArcGIS for Server. A code of 498 indicates an expired or otherwise invalid token.
499 Token Required (Esri)
Returned by ArcGIS for Server. A code of 499 indicates that a token is required but was not submitted.
499 Request has been forbidden by antivirus
Produced by some programs such as Wget when a malicious site is intercepted.
509 Bandwidth Limit Exceeded (Apache Web Server/cPanel)
The server has exceeded the bandwidth specified by the server administrator; > this is often used by shared hosting providers to limit the bandwidth of customers.
530 Site is frozen
Used by the Pantheon web platform to indicate a site that has been frozen due to inactivity.

RESTful status code for a request that cannot be satisfied because of a dependency issue

My payment endpoint which accepts a POST should deny requests when the user does not have any payment methods configured. What is the correct HTTP status code in this case?
What is the correct HTTP status code to be raised when the system itself cannot reach the state asked for by the request and another request (creating a payment method) must be completed first?
I looked at 428 Precondition Required, but that seems to have more to do with the headers than the state of the system.
I would go simply with 400 Bad Request. If you need more specific instructions or hints in the response, you can return a body, which will indicate the exact nature of the error.
You don't need to assign a specific HTTP error code to all your internal business-related error cases. Indeed this is probably not possible anyway.
The specification on 400: https://www.rfc-editor.org/rfc/rfc7231#section-6.5.1
Relevant quotes from there:
indicates that the server cannot or will not process the request due to something that is perceived to be a client error
And about the 4xx codes in general:
the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition
Did you look into error 424 Failed_Dependency? I think this could bethe one you want.
See
http://www.restpatterns.org/HTTP_Status_Codes/424_-_Failed_Dependency

400 vs 422 response to POST that references an unknown entity

I'm trying to figure out what the correct status code to return on different scenarios with a "rest-like" API that I'm working on.
This example is borrowed from another question about syntax type issues in the body, but my question assumes valid syntax throughout.
Let's say I have an endpoint that allows POST'ing purchases in JSON format. It looks like this:
{
"account_number": 45645511,
"upc": "00490000486",
"price": 1.00,
"tax": 0.08
}
What is the appropriate status code if:
the account number does not exist
the account is closed or the
account identified is not the right kind of account
These are all firmly business layer issues that prevent "processing" from occuring, however, one scenario involves something that in a GET would be a 404.
Note that the account number is not in the URL, so is 404 misleading?
Let's take these one at a time. Each of these codes is a signal to your client that the server is functioning correctly, and that something must be changed in the request before it can be successfully carried out.
HTTP 400
The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
400 typically indicates a syntax error; as a user, I should look at the structure of the request before trying again.
HTTP 404
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.
404 is the standard code used when a web server can't match a url path to anything. As a client, I should look at the URL of the request before trying again.
HTTP 422
The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415 (Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.
422 is generally used for content violations. As a user, I should look at the content of my request before trying again.
Now in your case, account number is an identifying number, but is not included in the URL. A 404 would signal to your user that the URL is wrong, not the payload. Stated another way, suppose your url is:
http://www.myservice.net/endpoint
A 404 would indicate to me that no service exists at /endpoint, instead of no account number. No matter what content I submit, the server will not process my request. The fix I should make then would be to look for an error in the URL, instead of the data payload. So to me a 422 would point me in the right direction, unless you begin to include the account number in the URL.
Ultimately these are design preferences, just make sure you communicate them clearly to your users.
If you consider the accounts to be part of the state of the resource (though indirectly) then you might also consider 409 since that state is in conflict with the semantics of the request.
However, 422 is gaining popularity via Ruby on Rails and Dropwizard where it is used to indicate non-syntactic issues with the body. That growing tendency represents a strong signal to a developer using the API that they need to exclude syntax and focus on the body. Developer time is usually the single largest cost your customers will ever incur, so by directing the attention of their developers you will keep them happy.
So 409 is a possible answer, though rather novel, and 422 is the more conventional approach, although obviously RoR and DropWizard are both rather new so these conventions can be said to be changing fast!
I'd say 422 is adequate in your case, but 400 isn't bad if it's consistent with the rest of your API. It's a common convention to use 400 as an umbrella error code when there's something wrong on the client side, but either the error doesn't fit a particular error code, or you don't want to use too many of them.
A 404 is definitely wrong if there's something wrong with the POST payload.
Case 1 : Account number doesn't exist.
This is a standard case for 404.
Case 2 : Account is closed.
This has do with the logic if you keep the account details when you close it.
If you donot keep the account details when the account is closed, you can give 404.
If you keep the account details after it is closed, you must be marking it (like raising some flag) (or whatever logic you have). In this case, Status code 400 with a proper message of why it is failed and possibly remediation will do.
Case 3 : Account identified is not the right kind of account.
403, as the account is not authorised for completing any purchases makes sense to me. If there is no concept like authorised account, 400 with a explanatory message will do. But I would insist to go with 403 in this case.
Actually, in this case 404 sounds good to me.

Should POST request return 404 if reference to other entity fails?

I'm building an API which operates on a noun Foo. When a caller creates an instance of Foo with a POST request, they are required to provide an ID to a second noun, Bar. If the ID they provided is of the right type but there is no Bar with that ID, is 404 the right response?
I think it depends on whether the ID is in the URL or not. The URL is the address for a resource, if the ID is in the URL and no item with this ID exists, or you don't provide it at all, then the URL is invalid, so no resource could be found, so that's a 404.
However, if the ID is not in the URL but in the data from the POST request, and the URL is a valid address to a resource, then a 400 Bad Request should be returned.
I would suggest using HTTP 400 (Bad Request).
See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1. One could interpret 400 as a generic indication that the client did not form the request correctly.
One could also make a case for returning a 500 response. If the client believes that the Bar reference is valid, then the server's failure to process this request could be viewed as exceptional. This could happen for example if the reference is valid, but the a different client deletes it. In this scenario, the first client is not doing anything wrong.
In short: No. Your API should be "user-friendly" meaning, if there is an error it should return it in a way that the user can figure out what the problem was. Returning 404 is like saying that the service was not found which is not true. The response should be 403 - cause it could be that the resource with the ID that the client tries to approach belong to a different client!
In addition, the response should contain an error message/code (in the body) which can be parsed and analyzed by the client.
This is a bit grey area.
Although the 500 response code looks like a good fit because of its broader context, the 404 response code could also be considered.
The reason that I am not sure about the 404 code is the main purpose of your request. The request is sent to create a new resource. It is not for retrieving an existing resource. Though the root cause is the "Not Found" resource, the intention of the request is for a new entity. Getting the 404 response code might cause ambiguity for the client. Therefore, the 500 with a good explanation looks like a better option.
I can clearly state that the 400 response code is not convenient for this case because there is nothing wrong with the request syntax.
The following definitions from MDN Web Docs - HTTP response status codes might help to make a decision.
400 Bad Request:
The server could not understand the request due to invalid syntax.
404 Not Found:
The server can not find the requested resource. In the browser, this
means the URL is not recognized. In an API, this can also mean that
the endpoint is valid but the resource itself does not exist. Servers
may also send this response instead of 403 to hide the existence of a
resource from an unauthorized client. This response code is probably
the most famous one due to its frequent occurrence on the web.
500 Internal Server Error:
The server has encountered a situation it doesn't know how to handle.
4xx is entitled "Client Error" in the standard
5xx is entitled "Server Error"
If the server is 100% sure that the reference to Bar could not be correct (that id is totally invalid format or couldn't have existed) then that's a straight up 400 Bad Request.
If the server allowed someone to delete that Bar where such deletion should not be allowed (Foo should go down with it) then that's a 500 Internal Server Error.
Here the client is creating a Foo with a dangling reference to a Bar (since it's a POST, if it were updating a Foo it would be a PUT). The client got a reference to the referenced Bar somehow and can presumably find an appropriate existing Bar if it tried again. In that case, the server returns 409 Conflict to signal that the request, while valid, is in conflict with the state of the server and needs to be dropped or reconstructed so that it is consistent with the state of the server. The 409 response should specify that the problem is that the referenced Bar does not exist.