Rest endpoint with success and a helpful warning - rest

I have a request from the client - when the user performs an action, there can be 3 actions:
the action succeeds with 200 OK status
the action fails (400) with an error message
the action succeeds but we need to display a helpful warning message to the user. This happens when the allocated amount is almost used up.
There does not seem to be a way for REST APIs to return an indication that the action completed successfully with some helpful information that further action might fail.
Thanks

HTTP response codes are limited and I think, those to be used to indicate any generic response. To have application specific response codes or response strings, it is better to have application level response codes to be communicated via HTTP response payload.

You didn't mention which HTTP method you are preparing for. Using GET should of course not modify anything, so I'm assuming it's either POST or PUT.
For POST, the response should be 201 Created. There should be a Location header line indicating the resource that was created.
For PUT, the response should be 200 OK.
In both cases, you can return a content body, as others suggested. This body can be some status information about the current state of whatever resource you are using. Note, that this status information might be reachable explicitly by some other URI, so it can share a mime-type with that "status" resource.

REST is using HTTP methods and HTTP status to represent the status of reply, by checking HTTP status I can find code 203 I think it could be suitable for your 3rd case :
203 Non-Authoritative Information (since HTTP/1.1)
The server successfully processed the request, but is returning information that may be from another source.

Related

Should I use different satus codes in restful api, instead only 200?

I'm developming RESTful API service. I've got disagreement between Me and my Team Lead, on the subject: "HTTP Response status codes".
My Team Lead talks, that default HTTP status codes written in RFC is awful and it's very hard to handle them on the client side(frontend). He thinks that custom status codes in response body, with HTTP status code 200 (every time 200) - the best way. His response body will like following, when trying to execute action without permissions:
HTTP/1.1 200 OK
{
code: 1005, // Custom code instead 403
data: {
message: "Forbidden."
}
}
I think that is wrong way to response. My response scheme will be like this:
HTTP/1.1 403 Forbidden
{
code: 403,
success: false,
message: "Forbidden."
}
Should we use RFC HTTP status codes, or we can use our own custom? Where is the best and right way?
The short
You are absolutely right.
The long answer
In restful API design you have to make use of the official HTTP codes specified in RFC-7231. Please do not send a 200 OK for every request. 200 OK is reserved for requests which actually succeeded and the server responds with a valid state of a particular resource. There are codes for most use cases. If you still need to differ errors of the same type, for example FORBIDDEN you may send a custom error code along. But the HTTP response is still an error therefore you shall not use 200 OK.
Regarding your proposed error scheme, you should not send the code and status within the body. This is already sent as the HTTP status and therefore redundant. Also a boolean success flag is redundant since the type of HTTP code already points out if it was a success or not (2xx => success, 4xx client error, 5xx server error).
The body should contain additional context which will help an API client to resolve the problem.
A well designed API error response should contain helpful information to fix a possible problem:
Request ID which gets generated per request on the server
Detailed error message
(Optional) Internal error code
(Optional) Error category
(Optional) Reference to the api documentation/error description
Example:
HTTP/1.1 403 Forbidden
{
"requestId": "a5e5dd13-0047-4d2e-b96c-55a5031f0511",
"message": "You are not allowed to access this resource. Missing write permission.",
"category": "AccessControl"
}
If this still is not enough for your team lead to believe you may point out some well designed REST API's:
GitHub API v3
Kubernetes API

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:

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

What status code should be sent when a user tries to sign up with a username that already exists?

I was thinking 403. From http://www.restapitutorial.com/httpstatuscodes.html:
The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
Edit: Endpoint - POST /users.
The normal HTTP error code for situations like this is 409 Conflict:
The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough
information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required.
This should be issued in response to a POST or PUT, typically as part of some sort of RESTful API. It should include a useful error message in addition to the status, and the error should be appropriately encoded (e.g. with XML or JSON).
Obscure HTTP errors are less useful in front-end web services. If you are developing a user-facing website, it's preferable to simply deliver an HTML page explaining the problem with a standard 200 OK.
If you are creating a REST API to create accounts, I would expect the request to be something like:
POST /accounts HTTP/1.1
{userid: "someone#example.com", password: "passw0rd!"}
In this case, I guess an appropriate response code would be 409 Conflict with an error description in the body
HTTP/1.1 409 Conflict
{ error: "Account already exists"}
That status code is for an HTTP error, not what you need. Also, it would be very unhelpful as it does not describe the problem at all.
Why not just send:
Username already exists! Please select another.
403 is an ok response in my opinion. 409 and 412 are also possible choices.