Reputation: 1009
So let's say I have two resources, Wallet and User. The User and Wallet have a one-to-one relationship. In my REST API, I give the option to give the User a different Wallet, by ID. So a typical HTTP PUT request to move the user to a different wallet could look like this:
PUT /api/user/3 HTTP/1.1
Host: api.myuserandwalletwebsite.com
{
"wallet_id": 15
}
This will update the User to use the wallet with id=15. But, what if the PUT request contains a wallet_id that is not found in the database; what should the REST API then return? Just a simple 404?
Returning a 404 on a sub-resource not found feels weird to me, because the 404 would be misleading: you could think the 404 actually refers to the user not being found.
Upvotes: 7
Views: 6667
Reputation: 13672
404 (Not Found)
is definitely not the correct response code. The response code you want is 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.
-- RFC 4918
It is a well-understood and well-defined response code, and can be found in the Hypertext Transfer Protocol (HTTP) Status Code Registry maintained by IANA.
As a side note, you're not using HTTP PUT according to the spec. A PUT should update the entire contents of the resource in an idempotent manner. You should be using either PATCH or POST.
As an alternative, you might consider a joining resource, such as a /user-wallet endpoint. That may or may not make sense depending on the specifics of your API.
Upvotes: 12
Reputation: 331
Like you already mentioned: I would also not use 404, because it would mean the user could not be found. As you want to update your User resource and this update fails due to invalid data (a reference to an invalid Wallet) I would rather use 400 Bad Request and add a meaningful message to an additional header field (e.g. X-Message: Wallet with ID 15 not found).
HTTP 422 Unprocessable Entity is also a good idea, but not covered in RFC2616. If this "extension" is no problem you can go with this one.
HTTP 405 is not correct here as this would mean the PUT method is generally not allowed on the users resource and that PUT would not be included when firing OPTIONS to the resource which is not the case.
Upvotes: 1
Reputation: 915
In my application that using REST-API I trying to follow best-practises described here: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api And I know many programmers from GOOD Software development companies that also take care about this. So as was described in best-practises in case of not found resources just simple use:
404 Not Found - When a non-existent resource is requested
That is first case - common best practises.
Second: thing behind best REST-API practisies is Your application logic: I think You have some options based on Your app-logic :
404 Not Found - When a non-existent resource is requested because You requested non-existing wallet
405 Method Not Allowed - You cant put because wallet not found and it is required for update
422 Unprocessable Entity - Used for validation errors because we have validation in our app that check for incomming requests
So concrete status is only Your decision. Remember the option that You choose will propagate for rest of Your logic application so be consistent and consider the REST-API like GUI dedicated for other application
Upvotes: -1