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

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).

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

Which status use when iterate into the same request?

I have a concern about which status code need to use in the following scenario:
Suppose that I have the following endpoint:
https://my-restaurant.api.com/v1/orders
And I made a POST request with some elements inside of the body to start a new order:
{
date: "2018-08-10T09:00:00.000-03:00",
order: 12345
}
The response would be the following:
{
require_additional_data: true,
customers: [],
waiter: "Jon Doe"
}
Here, the service tells that need more data before to close the order. The next step would repeat the request with the same body, but with more data about the order.
The response status code should be a 200 OK in this case? I guess that would be 200 OK once that the service tells that order was finished and have all the information required.
Until that, which status code would be used?
Don't use 200 for this situation. Keep in mind that 2xx status codes indicate that the request was successfully received, understood, and accepted by the server. That's not your case.
A 4xx status code would be more suitable for the situation described in your question. You could use 422 as pointed in the comments. It indicates that the request entitity cannot be processed due to semantic errors (but it's sintatically correct). See the definition below:
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.
It depends on the state cycle or constraints of your order ressource :
Can an order resource (in your database or any persistence layer) be empty?
If yes, you should return 200.
If no, you should return a 400 Bad request. You can also return a 422 who will be more precise.
Both are good answers.
If creating an order is for you a long process, which need multiple requests, then an order could be empty.
e.g. :
Create empty order
Add first meal
Add second meal
Add wine
If creating an order is one atomic request, or you don't want to see any empty order in your base the order cannot be empty.

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.

Indicating Invalid Value with Reason

I am designing an endpoint that a client will hit to register a tenant with an application; these tenants are represented as subdomains (<subdomain>.alex.com). I want to reserve all subdomains with length <= 4 (for example they can only be registered for select clients). What is the "right" HTTP error code to return to the user if they choose a subdomain <= 4 characters?
400 seems okay, but I am wondering if there is better.
One thought would be 422:
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.
The 422 code seems good for what you want to do, however I would also consider 403, which could also apply. I would prefer 403 over 422 for a couple of reasons, i.e. the code definition for 403 states that automatic repeats shouldn't be issued, or even just because is a more commonly used status code. However this is just my opinion. In both cases I think the server should also send a message explaining the problem, along with the status code.

Correct status code for no results because of an incorrect request

I've got a GET resource that takes a couple of parameters, let's call them CompanyId and CategoryId
This resource can return no results if either the CompanyId or CategoryId are invalid values (Ie: the CompanyId or CategoryId don't exist), or if they're valid, but we just don't have any data for them.
I'd like the client to be able to distinguish between the two cases, so simply returning a an empty 200 or 204 with no data for the former case isn't appropriate.
One way would be just to return a 200 with a message of "Company with Id of x does not exist, but this feels to me like a client error, they've supplied incorrect data.
Is it appropriate to use 422 'Unprocessable Entity' in this instance?
The HTTP response codes in the range of 4xx are for error in request, distinct from 5xx which are supposed to be sent after a server error.
Maybe in simple word:, 4xx if client or its request is bad, 500 if something went bad at server side.
400 Bad Request Is the standard and canonical status code for such event.
By default, web servers, web frameworks and also browsers will understand a 400 as Bad request but you should also provide a message in the response body explaining what went bad by the client.
See this Wikipedia article or this by W3C.
If your request isn't successful, you shouldn't use a status code 2xx.
I would rather return a status code 400 with a payload describing the problem (query parameter xx is required).
I would use a status 422 if a payload was sent with a method POST or PUT.
Hope it helps you.
Thierry