HTTP Status Code for Client being out of date - rest

I'm working on moving my REST API away from always responding with a STATUS: 200 OK containing an error key in the JSON returned if there was a problem, and trying to use the correct status codes in the event of problems.
So far I've moved most parts of my server over to the proper status codes 200, 201, 400, 401, 403, 404, 500, 501, and 503
Currently I'm trying to figure out what the best way of rejecting the access to a API call for a client that is out of date. Currently I'm sending the version of the client encoded with the Authorization token.
I'm stuck between using status code 426, and 412. The title of the 426 status code seems like the use case I would want, but the description has me a little concerned. 412 looks like it would be appropriate if i moved my versioning away from the authorization token and put it inside of it's own header.
This is my first REST API, and it works great, I'm just trying to convert it to following best practices. So I'm a little boggled.
TLDR;
Should I move my versioning into Headers and use Status 412
Should I use status code 426
Is there a code I'm missing here I should be using to request the client to update.
NOTE: My client is not a web browser. It is a mobile device.

Let us walk through your proposed solutions real quick: Status code 412 is now under authority of RFC 7232, section 4.2. It is to be used in the context of conditional requests if one or more preconditions described in section 3 of said RFC prevent the given request from being completed.
Code 426 is subject to RFC 7231, section 6.5.15. This code lets the client know that the [http] protocol version used to access a resource is too old to complete the request. Both of these codes do not apply here.
With a bit of help from this chart, I think two codes were adequate here:
Code 400 / Bad Request
400 is a bit vague (and deliberately so), indicating a general issue with the request.
Code 403 / Forbidden
This is a bit of a stretch as this code is indicating an authorization issue. However, it is not inherently linked to authentication, so you should be fine here.
Personally, I would go with 400. You may also want to take a look at RFC 7807 for a standardized way of transmitting API errors.

Hei Hobbyist...If you want to stick to official RFC release, then you should check the IETF site (Internet Engineering Task Force):
https://tools.ietf.org/html/
Not sure about which document, but for instance the HTTP/1.1 is part of RFC2616, but as I found in 2014 it was replaced by multiple RFCs (7230-7237).
The status 426 mentioned showed:
"
A server that sends a 426 (Upgrade Required) response MUST send an
Upgrade header field to indicate the acceptable protocols, in order
of descending preference.
A server MAY send an Upgrade header field in any other response to
advertise that it implements support for upgrading to the listed
protocols, in order of descending preference, when appropriate for a
future request.
https://www.rfc-editor.org/rfc/rfc7230#section-6.7 --> around page 57 you can find whole description :-)
"
Please have a look at those documents in order to decide which error code to give it back :-)
I hope this clarify your query. I wish you a nice day!

It would be a 4xx status code, but I don't think there is one specific to your use case. Thus, 400 should do. (You can send error details in the body, see, for instance, https://greenbytes.de/tech/webdav/rfc7807.html)

Related

HTTP response always return response code 200 even request fail, and return status code is part of REST

I recently joined a new project. In this project, all APIs in service always return status code 200. Even, if that response was should be 400 or 404, the API returns status code 200.
I asked the reason why APIs don't return other response codes, and programmers told me they don't use response code. they put information in the body.
for example, there are some missing required fields, they return response status code 200, but the body returns like this
{"result" : "fail"}
if an unauthorized user tries to access, the status code is 200, the body returns like this
{"result" : "unautherized"}
what I did before was very different, I always specified status code by cases and try to return suitable status code and message. I thought that this is the part of the HTTP protocol. However, they told me specifiying status code like 400, 404, 300, is part of RESTful API, and returning always 200 is the right status code because the server responded and it is alive. APIs, always have to return 200 except 500. Because when the server dies, it can't return anything.
So these are the question.
The server should always return status code 200 except the server dies?
Specifying various status code is the part of REST API?
Not using status code is common?
The server should always return status code 200 except the server dies?
I asked the same on Software Engineering a few years ago: Do web applications use HTTP as a transport layer, or do they count as an integral part of the HTTP server?. See also Should I use HTTP status codes to describe application level events.
Specifying various status code is the part of REST API?
No, REST is transport-agnostic. It can be used on top of HTTP, but doesn't need to. Therefore it doesn't say anything about status codes.
Not using status code is common?
Depends on who you ask.
It's a matter of preference. I extremely dislike "What is the most appropriate status code for scenario X?" questions. Also, there's:
HTTP Status Codes
HTTP Response Status Codes – REST API Tutorial
And plenty of others. I remember there being a site offering a flowchart for determining the (most) appropriate status code.
In general, don't bother. Consistency and thorough documentation is more important than assigning the appropriate number.
I've joined a project that uses exactly the same strategy -- embed status message inside the response body, and leave status code to be always 200. For consistency reason, it is better to follow existed strategy during the software maintenance time. However, it is not recommended for any new project, with reasons listed below:
"Specifying status code like 400, 404, 300" follows the RESTful design, but it is NOT part of REST. Actually, usage of 302 (redirect), 401 (Basic and Digest authentication), 404 (default not-found page in web server), 500 (default server error page) is popular decades ago, long before RESTful API these days (I know RESTful is proposed decades ago, but it is only popular in recent years).
"Returning always 200 is the right status code because the server responded and it is alive". This is incorrect. If it is, then only 200 can be used for status code -- as long as server is "alive", it can return message. 500 is not acceptable either, as in that case, server is still "alive", it does not die... Then, as the status code should always be 200, why do we need the code?
"Not using status code is common?". Actually, it is opposite. As RESTful API design scheme is more and more popular, more projects are using HTTP status code to deliver message semantics. But anyway, this is an opinion-based viewpoint.
What the team is doing may be completely appropriate for the circumstances that they are in. But labeling those patterns as REST sounds inaccurate.
I say this, because it sounds like the team hasn't given any thought to how their current messaging scheme works with generic participants in the message exchange.
For instance, caching is an important concern in the REST architectural style. In HTTP, RFC 7234 describes the caching semantics. In particular, there's a section on how cache invalidation is triggered by status codes. This in turn says that, if you aren't distinguishing between the status codes in successful and unsuccessful cases, then the generic components are going to be invalidating cached entries which shouldn't be invalidated.

what should be the appropriate http status code for POST API request when trying to create resources beyond maximum limit

I searched almost 2-3 hours for proper response code for below POST API but i did not get proper answer so I kindly request someone to help me here.
We have a POST API which creates resources maximum 10 times.
When we call POST API for 11th time, we should get a response with message "User exceeded the limit to create resource" and proper response code.
Please suggest what should be the proper response code.
With the level of details provided in your question, I would suggest a status code in the 4xx range, along with a response payload that describes the error in a meaningful way for the client.
You could consider 403 (Fobidden), expressing that the server understands the request, but refuses to authorize it. However there might be other status codes more suitable for your situation, depending on what your are trying to achieve:
402 (Payment Required): If the quota of requests has been exceeded, but more requests could be performed upon a payment, you could consider the 402 status code (even though the documentation says it's reserved for future use, its reason phrase is pretty clear and defines well its purpose).
429 (Too Many Requests): If you are applying restrictions on the number of requests per hour/day, the 429 status code may be suitable for your needs. However this status code is used by a server to indicate that too many requests have been received in a short amount of time, that is, the client is throttling.
If these status codes don't seem to match, simply go for 400, which expresses a bad request.
Status codes indicate the result of the attempt to understand and satisfy the request.
But you have to keep in mind that status codes are sometimes not sufficient to convey enough information about an error to be helpful. That's why you are advised to return a payload that describes the error. The RFC 7807 defines a standard for that.
If you create your own status code for that (what you could do, but doesn't mean you should do), be aware that clients will treat unrecognized status codes as being equivalent to the x00 status code of that class. From the RFC RFC 7231:
For example, if an unrecognized status code of 471 is received by a client, the client can assume that there was something wrong with its request and treat the response as if it had received a 400 (Bad Request) status code. The response message will usually contain a representation that explains the status.
You should try to use a 4xx status. Personally, I would use 403 because the user is forbidden to create the object.
The HTTP 403 Forbidden client error status response code indicates that the server understood the request but refuses to authorize it. This status is similar to 401, but in this case, re-authenticating will make no difference. The access is permanently forbidden and tied to the application logic, such as insufficient rights to a resource.
source
And then you can add a message to the request body explaining why the request is not successful. Some more info about 403
Also, I like to check this page if I need an overview of all status codes: Status Codes
I would suggest 400, Bad Request.
403 is more for authorization issues which this is not.
Provide a clear explanation why you're returning 400 and you're good to go.
Yes, it's a more generic solution, which is exactly what makes it more appropriate.
HTTP status codes have very clear use cases which are understood by everyone. It is not advisable to "reuse" one for something else.

HTTP Error Code 406

I understand that correct use of HTTP Status codes is a good indicator of correct RESTful implementation of a service. I'm not sure what code to return when the following resource is called with an invalid token to confirm creation of a new user account:
/user/confirmation POST {param is confirmation token}
By best guess is 406 Not Acceptable? But maybe it's a 200 because there is no error as such in which case the response much include information to indicate a failed confirmation?
Both 406 and 200 are unsuitable for this situation:
406 is meant for content negotiation, when the server cannot send a representation of a particular resource with the media type indicated in the Accept header of the request.
200 must be used when the operation has succeeded, what's not the case.
You could probably go for the generic 400 to express a bad request or go for 403 to indicate that the request is forbidden.
Sending the right status code is as important as proving a payload that describes the problem and helps your client to determine the cause of the error.
For reporting problems in your HTTP API, I advise you to have a look at the RFC 7807: it defines simple JSON and XML document formats to inform the client about a problem in a HTTP API and also defines the application/problem+json and application/problem+xml media types.
Michael Kropat put together a pretty useful set of diagrams to determine the most suitable status code for each situation. See the following diagram for 4xx status codes:

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.

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.