What HTTP error code should I use when trying to insert an already existing object? - rest

I'm designing a REST API. Some methods of this API are used to insert new data using the POST method. I'm wondering what error code to return when the insertion would result in duplicate data being inserted? I tried looking at the error code reference, but being quite new to REST and HTTP I'm not sure which one to use.

409 Conflict seems appropriate for that case.
The W3C status code definitions document says:
10.4.10 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.

Related

GET or POST for stateless RESTFUL API

I'm writing a stateless API. You send it a document, it processes the document, and then returns the processed document. I'm struggling to understand how the RESTFUL rules apply. I'm not retrieving data, creating data or updating data on the server. There is no data on the server. What do I need to use in this case as the http method and why?
Good news - you are right that it is confusing.
Nothing on the server changes in response to the request. That suggests that the request is safe. So GET is the natural choice here... BUT -- GET doesn't support message payloads
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
HEAD, the other ubiquitous safe method, has the same problem (and is unsuitable when you want to return a document in any case).
The straight forward thing to do at this point is just use POST. It's important to realize that POST doesn't promise that a request is unsafe, only that it doesn't promise that it is safe -- generic components won't know that the request is safe, and won't be able to take advantage of that.
Another possibility is to look through the method registry, to see if somebody has already specified a method that has the semantics that you want. Candidates include SEARCH and REPORT, from the WebDAV specifications. My read of those specifications is that they don't actually have the right semantics for your case.
A Lot of ways to do what you want. But here is a small guideline.
I would create an endpoint that receives the document:
/receive_document
with a 'POST' method. Since you are 'sending' your document to the server
I would create an endpoint that serves up the processed document:
/processed_document
with a 'GET' method. Since you want to retrieve / see your document from the server?
The problem that you are trying to solve is mainly related to the document size, and processing time before returning the response.
Theorically, in order to use a restful approach, you have an endpoint, like yourhost.com/api/document-manager (it can be a php script, or whatever you are using as backend).
OK, so instead of naming the endpoint differently for each operation type, you just change the HTTP method, I'll try to make an example:
POST: used to upload the document, returns 200 OK when the upload is completed.
GET: returns the processed document, you can also return a different HTTP code, in case the document is not ready or even different if the document hasn't been uploaded. 204 no content or 412 precondition failed can be good candidates in case of unavailable document. I'm not sure about the 412, seems like it's returned when you pass a header in the request, that tells the server which resource to return. In your case, I think that the user processes one document at time. But to make a more solid api, maybe you can return an ID token to the user, into the POST response, then forward that token to the GET request, so the server will be able to know exactly which file the user is requesting.
PUT: this method should be used when updating a resource that has been already created with POST
DELETE: removes a resource, then return 204 or 404
OPTIONS: the response contains the allowed methods on this endpoint. You can use it to know for example which privileges has the currently logged user on a resource.
HEAD: is the same as a GET call, but it shouldn't return the response body. This is another good candidate for you to know when the document has been processed. You can upload with POST, then when the upload is done, start some kind of polling to the same endpoint with the HEAD method, finally when it will return "found", the polling will stop, and make the final GET call, which will start the download of the processed document.
HTTP methods are a neat way of managing HTTP communications, if used properly are the way to go, and easily understandable by other developers. And not to forget, you don't have to invent lots of different names for your endpoints, one is enough.
Hope that this helped you a little... But there are loads of guides on the net.
Bye!

Proper HTTP Error for Deleting Non-empty Resource

I use 204 (No Content) to show that the server has fulfilled the delete request of a folder, and 404 for cases where a folder can not be found. I want to issue an error if the DELETE verb is issued for a non-empty folder. What would be the proper HTTP response status code for this situation?
I believe the correct one would be 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.
http://www.restapitutorial.com/httpstatuscodes.html says 409 should be used whenever a resource conflict would be caused by fulfilling the request. Duplicate entries and deleting root objects when cascade-delete is not supported are a couple of examples.

Appropriate HTTP status for a PUTting a read-only entity

What is the appropriate HTTP response code when a client tries to PUT to an entity that is currently read only by nature?
A toy example is a product shipment. Before the shipment is sent, the details (address, products, quantities) can be changed (e.g. with a PUT request). However, as soon as the shipment is sent, any PUT should fail, even if the request format and syntax are correct.
It's possible that the client doesn't know that the shipment has been sent, so it's not a "careless" error on the client side.
400 doesn't seem appropriate, because the input is well formed and the syntax is correct.
405 seems like a good fit. Is this a common response in this case?
403 seems to imply authorization has been revoked, which could be misleading.
422 seems to fit well, but its use seems discouraged if you don't provide WebDAV capabilities (which we don't).
500 makes it sound like someone tripped over a cable, though I hear some developers/frameworks use this status in this case.
Is there a standard practice for this case? What is least likely to cause confusion for the API user (developer) and the end user (person using the UI)?
I would look at 405 Method Not Allowed. It is defined like this:
The 405 (Method Not Allowed) status code indicates that the method
received in the request-line is known by the origin server but not
supported by the target resource. The origin server MUST generate an
Allow header field in a 405 response containing a list of the target
resource's currently supported methods.
Your server understands the request perfectly, but it no longer supports writing. In addition, the requirement to return the client the list of supported methods sounds clean.
As an added bonus, the 405 response is cacheable by default, which could make sense in your case.
Another viable alternative is 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.
Arguably the order changed state, in such a way modifying it is no longer possible. Note however that:
This code is used in situations where the user might be
able to resolve the conflict and resubmit the request.
…so I would tend toward the other one.

Status code to return on not found sub-resource

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

Asp.NET Web Api: Returning meaningful errors to client?

I have created myself a standard asp.net web api project and it has a Post on there.
The post basically will insert some values into a database but before doing so I need to do a number of different checks on an alternative database, if anything doesn't check out I want to return the client with a NON 200 http status code but which should I use?
What is the recommended status code to return? I would also like to return some text with it which would contain additional information that could identify what the error was.
Or is it recommended to return 200 and an additional JSON payload identifying if there was a problem and what it is
Does anyone have any examples??
Thanks in advance
400 BadRequest could be used if what you are performing is validation logic and this validation logic fails for some reason. As far as the additional information is concerned, you might return some info in the body, for example as JSON payload:
{
"errorMessage":"Validation failed because user doesn't exist in alternative database"
}
If on the other hand you are attempting to update an entity that doesn't exist, you could also send a 404 status code.
In addition to what Darin stated on this thread, here is a good reference on status codes. I have also found this article valuable in handling errors with ASP.NET WebAPI.