REST API - appropriate response statuses - rest

I'm designing a REST API. I would like to know what are the most appropriate http statuses in the 2 following scenarios:
A user tries to register and:
Username already exists.
OR:
Password and password repeat fields do not match.
Thanks.

Username already exists
409 Conflict sounds correct for this situation.
Password or password repeat fields do not match
This is a general error on the client side. Use 400 Bad Request for this.
See https://en.wikipedia.org/wiki/List_of_HTTP_status_codes for more.

409 status code is a good choice for a username that already exists:
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.
400 status code is just fine for passwords that do not match:
6.5.1. 400 Bad Request
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).

Related

api status code for post request that has failed

I have an post api call that currently creates an appointment in my booking system.
If the api call sends the appointment request and the api can successfully create an appoinment the api returns a 201 created status code.
Currently if the appointment request is not created (due to various things such as the time is no longer available or the room is now being used) the api is returning a 400 bad request status code.
"400 Bad Request response status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error"
The data sent is not invalid syntax and potentially could be resent and be successful.
Is there a more relevant status code for this failure to create a resource. would 422 Unprocessable Entity be a valid response in this case?
409 could suit this use-case(and my personal preference):
"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."
Typically used in PUT but could work in this scenario. For example, they could change the proposed time in the request. Or they could retry later if the room becomes available.
422 could also work to indicate a field level error.
Either way, an important thing is to accompany it with a good error message indicating the issue. From rfc7231:
the server SHOULD send a representation containing an explanation of
the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method.
[... ] if the appointment request is not created (due to various things such as the time is no longer available or the room is now being used) [...]
Status codes are meant to indicate the result of the server's attempt to understand and satisfy the client's request. Given that it's a client error, the most suitable status code would be in the 4xx range.
For the situation described in your question, you could use 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. [...]
400 vs 422
In general, use 400 to indicate syntax errors in the payload or invalid parameters in the URL. And use 422 to indicate semantic problems in the payload. See how each status code is defined:
6.5.1. 400 Bad Request
The 400 (Bad Request) status code indicates that the server cannot 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).
11.2. 422 Unprocessable Entity
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.
Also consider the status codes returned by the well-known GitHub API v3 API:
There are three possible types of client errors on API calls that
receive request bodies:
Sending invalid JSON will result in a 400 Bad Request response. [...]
Sending the wrong type of JSON values will result in a 400 Bad Request response. [...]
Sending invalid fields will result in a 422 Unprocessable Entity response. [...]
Michael Kropat put together a set of diagrams that's pretty insightful when it comes to picking the most suitable status code. See the following diagram for 4xx status codes:
My suggestion would be to use 412 Precondition Failed Status code which indicated that server couldn't process the POST request due to failure/denial of additional criteria or business logic.
Refer: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412
If the error is due to something going wrong on the server and to no fault of the client you can use the 5xx range (Server Error). 4xx errors are reserved for errors caused by the client. Most often 500 Internal Server Error is used in this case.
So:
Clients fault --> 4xx
Servers fault --> 5xx

422 or 409 status code for existing email during signup

I am building RESTful API and I have come across a situation. During user sign up, if the email already exists then between 422 and 409 which http response code makes sense?
I have browsed through similar one and the accepted answer is from the year 2012. Does the answer still hold good? Examples would be of great help.
You may not find a very definitive answer to this question, once both 409 and 422 would be suitable for this situation (I would go for 409 though).
For any of them, you must ensure that a payload describing the problem is sent back to the client.
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. [...]
11.2. 422 Unprocessable Entity
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.
I think 409 is most appropriate in this described example as the request is conflicting with an already existing registration.
For example, if the service couldn't accept a .de domain based email address; 422 seems preferable. This example would also not qualify for a 400 as a .de domain would be valid syntax.

HTTP status while POST with incorrect data (using id of resource which does not exist)

What would be the correct HTTP status to return when I am performing the POST request to create a new user, but one of its parameters is incorrect - the company id I am including with the user data doesn't exist in the database.
POST
data: {username: 'newuser', age: 99, company_id: 34}
the company with id 34 does not exist in the database.
I was thinking whether that could be:
400, kind of invalid data, but it is valid but nonexistent id
404 - but it is not so clear which resource does not exist
409, because it is kind of conflict and the user can resolve that by changing the company id
422?
or 500 - because it is kind of database error while non existing id's are not allowed there
400 or 422
First of all, keep in min that it's a client error, so 5xx status codes are not suitable here. You should pick a 4xx status code then.
The most obvious options are 400 and 422:
If the JSON is syntactically invalid, return 400.
If JSON is syntactically valid but its content is invalid, return 422 to indicate that the request entity cannot be processed by the server.
See the following quote from the RFC 4918 (for your situation, just read JSON when it says XML):
11.2. 422 Unprocessable Entity
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.
A similar situation was addressed in this answer.
For example purposes, the GitHub API v3 also returns 422 if the content of the payload contains invalid values (but is syntactically valid):
There are three possible types of client errors on API calls that
receive request bodies:
Sending invalid JSON will result in a 400 Bad Request response. [...]
Sending the wrong type of JSON values will result in a 400 Bad Request response. [...]
Sending invalid fields will result in a 422 Unprocessable Entity response. [...]
Michael Kropat put together a set of diagrams that's pretty insightful when it comes to picking the most suitable status code. See the following diagram for 4xx status codes:
404 Not Found is a problematic status to return for a POST request. It implies the resource you are sending the request to doesn't exist; the caller got the URL wrong.
The most obvious (and generic) answer is: 400 Bad Request
This just indicates there is something wrong with your request (the fault lies with the caller not the server) and then express the specific detail of what went wrong in your response body. This is typically how request validation is handled.
The ideal answer is to make it so you add a user by sending a request to the company they are a member of:
POST /company/34
Content-Type: application/json
{
"username": "newuser",
"age": 99
}
This means the caller has to find a valid company resource to send the request to. If company/34 doesn't exist, a 404 Not Found response is appropriate; you tried adding a user to a company which does not exist.
This does mean your API has to be structured with resource semantics and a user has to belong to exactly one company.
Here, this picture is very good, and I've used it many times.
Which code should I return?
I'd go with 404. The resource could exist (not a format error) but it just doesn't (and hence can't be found).

REST-API HTTP status code for invalid input on a Patch request

There is a Patch request on my application that updates a user's password. We have an Ember validator to block all invalid input except for 1 business rule, which is it should not be a password used as one of your past 5 passwords.
We are currently returning a 400 Bad Request in this case, however my company has a dashboard for component availability and counts 400 and 500 requests as unavailability, because most applications are SOAP and they just expect 200 and 300s. Even though we handle this 400 appropriately through the UI it is still a ding against us. And puts us on the radar as an area with poor availability.
Should we take this to the people that monitor availability and have them change this for REST services as this will become a more common and common occurrence as the company creates more REST applications. Or do we cave and return a 200 that also states that the password was not successfully updated?
I would argue that a 400 response is inappropriate for the service. If the service is responding with a 400 when the user's password has been repeated within the last 5 passwords, then the request was understood by the server.
According to the W3C:
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.
In your case, the request was understood. It is returning a 400 to signal an application concern (regarding password reuse). I believe a 200 response would be more appropriate with a payload indicating the application problem.
EDIT:
One might also argue that a 422 response would be in order:
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.

on POST what if entity exists - what is the correct response

I have a RESTful API where one can GET Nodes and Post Nodes - basic stuff.
My "problem" is this:
When a user posts a new node, and that node already exists.
Should I return
400 bad request
409 conflict
200 and the existing node
Im leaning towards 200 and returning the existing node.
But the 409 and then letting the user get the correct node by themselves seems more "correct" if you will.
What is the "best practice" in this matter, for RESTful api's?
The expected result of a POST is the creation of a new resource along with a 201 CREATED status code. Returning 200 OK is not appropriate because the request was not a success. Also see the RFC:
200 OK
The request has succeeded. The information returned with the response
is dependent on the method used in the request, for example:
GET an entity corresponding to the requested resource is sent in the
response;
HEAD the entity-header fields corresponding to the requested resource
are sent in the response without any message-body;
POST an entity describing or containing the result of the action;
Was there something wrong with the request? No. So 400 BAD REQUEST is not really appropriate either.
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
Is the user able to resolve the conflict? Yes, probably. If the conflict arises for example because a username is already taken, you can return that as error message to the user so that he can pick another username and thus resolving the conflict.
I would go with the 409.