RESTful - What should a DELETE response body contain - rest

Let's say I have an API where you can get users:
GET /RESTAPI/user/
And you can delete users by:
DELETE /RESTAPI/user/123
What is the RESTful convention on what the DELETE's response body should contain?
I expected it should be the new list of all users which now doesn't contain the user with id 123 anymore.
Googling around didn't get me any satisfying answers. I only found opinions on how to do that, but isn't there a strict definition of RESTful Services?
This is NOT a duplicate of What should a RESTful API POST/DELETE return in the body? and What REST PUT/POST/DELETE calls should return by a convention?
since this questions asks for a strict definition regarding DELETE. Those questions were answered by loose opinions only.

The reason you get no hard answers is because there is no hard RESTful standard. So I can only suggest that you create a hard standard and stick to it within your own APIs
I used this as a guide for RESTful services http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
It says respond with a 204 status and an empty body
I stick to those standards and document them well for anyone who wants to use my APIs

What is the RESTful convention on what the DELETE's response body should contain?
REST is an architectural style defined by Fielding in the chapter 5 of his dissertation and it describes a set of contraints for applications built with this architecture. REST is designed to be protocol indenpendent but the chapter 6 of the same dissertation describes how REST is applied over HTTP.
Once your REST application is designed on the top of the HTTP protocol, you should be aware of the HTTP semantics. And the semantis of the HTTP/1.1 protocol are currently described in the RFC 7231.
The response payload of a DELETE request that has succeeded may:
Be empty or;
Include a representation of the status of the action.
And the following response status codes are suitable for a DELETE request that has succeeded:
202: The request has been accepted for processing, but the processing has not been completed.
204: The server has successfully fulfilled the request and that there is no additional content to send in the response payload body.
200: The request has succeeded and the request payload includes a representation of the status of the action.
See the following quote from the RFC 7231:
If a DELETE method is successfully applied, the origin server SHOULD
send a 202 (Accepted) status code if the action will likely succeed
but has not yet been enacted, a 204 (No Content) status code if the
action has been enacted and no further information is to be supplied,
or a 200 (OK) status code if the action has been enacted and the
response message includes a representation describing the status.

204 No Content is a popular response for DELETE and occasionally PUT as well.
However, if you are implementing HATEOAS, returning a 200 OK with links to follow may be more ideal. This is because a HATEOAS REST API provides context to the client. Think of the location a user application navigates to after successfully issuing a delete command. Here is a brief article excerpt with more discussion on this. See the blog article for a more complete discussion.
Article: http://blog.ploeh.dk/2013/04/30/rest-lesson-learned-avoid-204-responses/
Avoid 204 responses if you're building a HATEOAS application.
This is a lesson about REST API design that I learned while building non-trivial REST APIs. In order to be as supportive of the client as possible, a REST API should not return 204 (No Content) responses.
From the service's perspective, a 204 (No Content) response may be a perfectly valid response to a POST, PUT or DELETE request. Particularly, for a DELETE request it seems very appropriate, because what else can you say?
However, from the perspective of a proper HATEOAS-aware client, a 204 response is problematic because there are no links to follow. When hypermedia acts as the engine of application state, when there are no links, there's no state. In other words, a 204 response throws away all application state.
This article covers POST, PUT, DELETE and GET. Here's the specific discussion on DELETE:
Responding to DELETE requests
A DELETE request represents the intent to delete a resource. Thus, if the service successfully handles a DELETE request, what else can it do than returning a 204 (No Content)? After all, the resource has just been removed.
A resource is often a member of a collection, or otherwise 'owned' by a container. As an example, http://foo.ploeh.dk/api/tags/rock represents a "rock" tag, but another way of looking at it is that the /rock resource is contained within the tags container (which is itself a resource). This should be familiar to Atom Pub users.
Imagine that you want to delete the http://foo.ploeh.dk/api/tags/rock resource. In order to accomplish that goal, you issue a DELETE request against it. If all your client gets back is a 204 (No Content), it's just lost its context. Where does it go from there? Unless you keep state on the client, you don't know where you came from.
Instead of returning 204 (No Content), the API should be helpful and suggest places to go. In this example I think one obvious link to provide is to http://foo.ploeh.dk/api/tags - the container from which the client just deleted a resource. Perhaps the client wishes to delete more resources, so that would be a helpful link.

Related

Http Status for partial response in the case where API makes calls to multiple APIs

I have an API whose job is to aggregate resources obtained by calling multiple other APIs and then give out the aggregated response to the client. Currently even if one or more dependent API calls fail, I go ahead and aggregate response from the other dependent APIs and then give them out to the client with a 2xx status. In case all of the dependent API calls fail, I still give out a 2xx with empty list.
In case one or more dependent API calls fail, I want to give out an indication to the client. I was thinking of using the HTTP code 206. What would be the best approach to handle this scenario. Is giving out a 206 with the names of the dependent services that failed to give out a 2xx as part of a header the correct approach. If yes, what should this header be called?
I was thinking of using the HTTP code 206.
I can't promise, but that seems like a very bad idea; see RFC 7233
The 206 (Partial Content) status code indicates that the server is successfully fulfilling a range request
If the client didn't send you a range request (see RFC 7233 for the specifics), then I don't think there is any benefit in answering as if it had. General-purpose components are likely to get confused.
As for what status code to use instead: the response code, like the headers, is meta data so that general purpose components can understand what is going on and provide intelligent assistance. The details of what you are doing, that are to be understood by the bespoke client, belong in the response body.
(Analogy - on the web, the status code and the headers are for the (general purpose) browser. The response body is for the human being.)
200 OK is probably what you want to be using here; with a "representation of the status of the action" in the payload.

HTTP Status-code for empty response and response not found

We are implementing a REST based web service and we have some queries on some of the use cases.
Consider there is a unique account which contains some information (Ex. added to cart information)
What response code should we return if no cart information exists (Ex. 0).
Our understanding was to return 200 with empty response.
User added cart information to his account, but cart is removed by admin.
What HTTP statuscode shall be used?
For situation 1 there are two options:
The cart is empty. I would return 200 OK returning an empty collection.
The cart doesn't exist. The correct case for this is 404.
For situation 2, it's really the same. The only potential difference is that if you returned 404 for situation 1, you could choose 410 gone, as it indicates that a cart was here before, but it's now gone.
Regardless of which you choose, I would recommend you take the same strategy for both situations. E.g.: Either return a 2xx code for both or a 4xx code for both.
If the admin deleted the cart by doing a DELETE request, then the 404/410 status codes are more appropriate.
See This Blog. It explains it very well.
Summary of the blog's comments on 204:
204 No Content is not terribly useful as a response code for a
browser (although according to the HTTP spec browsers do need to
understand it as a 'don't change the view' response code).
204 No Content is however, very useful for ajax web services which may want to indicate success without having to return
something. (Especially in cases like DELETE or POSTs that don't
require feedback).
The answer, therefore, to your question is use 404 in your case. 204 is a specialized reponse code that you shouldn't often return to a browser in response to a GET.
The other response codes are even less appropriate than 204 and 404.
200 should be returned with the body of whatever you successfully fetched. Not appropriate when the entity you're fetching doesn't exist.
202 is used when the server has begun work on an object but the object isn't fully ready yet. Certainly not the case here. You haven't begun, nor will you begin, construction of user 9 in response to a GET request. That breaks all sorts of rules.
400 is used in response to a poorly formatted HTTP request (for instance malformed http headers, incorrectly ordered segments, etc). This will almost certainly be handled by whatever framework you're using. You shouldn't have to deal with this unless you're writing your own server from scratch. Edit: Newer RFCs now allow for 400 to be used for semantically invalid requests.
Wikipedia's description of the HTTP status codes are particularly helpful. You can also see the definitions in the HTTP/1.1 RFC2616 document at www.w3.org

RESTful API: Delete Entity - What should I return as result?

I am implementing a RESTful API and an endpoint of one controller is Delete. Delete does two actions depending of the entity to be removed: it updates the entity or it deletes the entity from the database. If delete updates the entity I would send the HttpStatus 200 and the updated entity. But if the delete removes the entity from the database I would send only the HttpStatus 200. In one case I am returning an object. But in the other case, the object doesn't existe any more. Is it a good approach or I am missing anything?
Short answer
The suitable status codes for a DELETE request that has succeeded are 200, 202 and 204.
Long answer
DELETE does two actions depending of the entity to be removed: it updates the entity or it deletes the entity from the database. [...] Is it a good approach or I am missing anything?
The DELETE method is not meant for performing updates.
See the following quote from the RFC 7231, one of the documents the define the HTTP/1.1 protocol, for details on what the DELETE method is about:
4.3.5. DELETE
The DELETE method requests that the origin server remove the
association between the target resource and its current
functionality. In effect, this method is similar to the rm command
in UNIX: it expresses a deletion operation on the URI mapping of the
origin server rather than an expectation that the previously
associated information be deleted. [...]
If the delete operation has succeded, the server can return one of the following status codes:
202: Indicates that the request has been accepted for processing, but the processing has not been completed.
204: Indicates that the server has
successfully fulfilled the request and that there is no additional
content to send in the response payload body.
200: Indicates that the request has succeeded and the request payload includes a representation of the status of the action.
See the following quote from the same document:
If a DELETE method is successfully applied, the origin server SHOULD
send a 202 (Accepted) status code if the action will likely succeed
but has not yet been enacted, a 204 (No Content) status code if the
action has been enacted and no further information is to be supplied,
or a 200 (OK) status code if the action has been enacted and the
response message includes a representation describing the status.
The commonly considered HTTP Statuses for DELETE include:
200 OK (MDN)
202 Accepted (MDN)
204 No Content (MDN)
204 is ideal if your service is not returning any additional info. It is also popular for PUT update requests. Many services return 204 including Docker as shown below:
Ref: https://docs.docker.com/engine/api/v1.24/
However, if you are implementing HATEOAS, it is better to use 200 OK and provide some links for the service. Think of an application that has just issued a delete and needs to navigate a user to a location. Without providing a URL for that location, the client app needs to keep state. Providing a 200 OK with a link allows the REST API to keep state for the client.
The following article describes this issue well (read the blog for more discussion):
Avoid 204 responses if you're building a HATEOAS application.
This is a lesson about REST API design that I learned while building non-trivial REST APIs. In order to be as supportive of the client as possible, a REST API should not return 204 (No Content) responses.
From the service's perspective, a 204 (No Content) response may be a perfectly valid response to a POST, PUT or DELETE request. Particularly, for a DELETE request it seems very appropriate, because what else can you say?
However, from the perspective of a proper HATEOAS-aware client, a 204 response is problematic because there are no links to follow. When hypermedia acts as the engine of application state, when there are no links, there's no state. In other words, a 204 response throws away all application state.
If a client encounters a 204 response, it can either give up, go to the entry point of the API, or go back to the previous resource it visited. Neither option is particularly good.
Ref: http://blog.ploeh.dk/2013/04/30/rest-lesson-learned-avoid-204-responses/

To PUT, POST or PATCH?

I have a REST Service that can be used to control databases, I want to allow calls to Stop & Start the databases, but was wondering what would be the correct Method?
By calling the Stop or Start Operation I am changing the state of the resource so a PUT seems sort of right, but is PATCH better or even POST?
Any suggestions?
Replacing the state of a resource
REST is protocol independent and is a resource-oriented architecture. When implementing REST applications over the HTTP protocol, for example, the resource is identified by the URI and the operation over the resource is expressed by the HTTP method.
PUT is the HTTP method used to replace the state of a resource and the new state of the resource will be expressed in the request payload using, for example, JSON and/or XML.
So you could consider the following design to start/stop a database:
PUT /databases/:id/status HTTP/1.1
Content-Type: application/json
{
"value": "started"
}
PUT /databases/:id/status HTTP/1.1
Content-Type: application/json
{
"value": "stopped"
}
To obtain the state of a resource, use GET:
GET /databases/:id/status HTTP/1.1
Response status codes
You certainly will need to inform your client about the result of the operation. To do it, use the HTTP response status codes.
A few status that might be useful:
200: Use this status to indicate that the request has succeeded.
202: Use this status code to indicate the request has been accepted for processing, but the processing has not been completed.
204: Use this status code to indicate the server has successfully fulfilled the request and that there is no additional content to send in the response payload body.
409: Use this indicates that the request could not be completed due to a conflict with the current state of the target resource.
Jim Webber explains that "HTTP is the application protocol of transferring documents" The transitions of state in your application are a side effect triggered by the document transfer.
Think old fashioned paper driven business office: the boss comes along and drops a TODO message in your inbox, which says "stop the database". As a side effect, you swivel your chair around and initiate the clean shutdown procedure.
Idiomatically, therefore, the representation you are sending to the REST server is that of the TODO message, and you are sending it to either (a) a resource that represents the "inbox" -- ie, a specific collection of TODO messages -- or (b) a resource that represents the TODO document itself.
I have a REST Service that can be used to control databases, I want to allow calls to Stop & Start the databases, but was wondering what would be the correct Method?
By calling the Stop or Start Operation I am changing the state of the resource so a PUT seems sort of right, but is PATCH better or even POST?
Since you are sending a complete message, rather than trying to make a modification to a message that the REST server already knows about, PATCH is not appropriate.
DELETE is also not appropriate - delete is analogous to destroying the TODO message in the inbox.
If the media type that you are using to represent application state at the client is HTML, then the verb you use shall be POST, because HTML doesn't support PUT.
If you are delivering a representation of a single message to a resource that represents a collection, then the verb you use shall be POST, because the semantics of PUT imply "create/overwrite" of a resource, and the semantic you are expressing is append.
If you are delivering a representation of a single message to a resource that represents that message alone (ie: you are doing a create of the message resource), then PUT is preferred to POST. The key idea here is that PUT promises that any side effects on the server are idempotent -- the side effect of successfully delivering N > 0 copies of the message are equivalent to the side effect of delivering exactly 1 copy. Using PUT as the verb shares that promise, not just with the client and server, but also with all of the intermediate connectors along the way.
Your idempotent resources can also support POST, and you can document in your API that the messages received are handled idempotently so that clients will understand, but there's no standardized way to inform the other connectors of this fact.
(Example: think about a form post in a browser. The resource at the server knows that the request can be handled idempotently. You can document in the html itself that hitting the button more than once is safe, but you don't have any way to tell the browser that, so the browser throws up a message to the user saying "re-POST might not be safe, are you sure Y/N?")
In summary, you want your choices of HTTP methods to agree with the uniform interface, so that the client, the server, and all of the components acting on the messages in between have a shared understanding of what's going on.

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