To PUT, POST or PATCH? - rest

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.

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!

Why HTTP Rest has different methods like GET, PUT, POST instead of just one or no method at all?

Why do we have different methods for HTTP request. GET can not send data(body) and can only request something only through URL params. Put is like changing a field value on the server and Post performs an operation everytime we execute it (concept of Idempotence).
Why can't there be one method or no method at all ?
Why can't there be just a simple HTTP request where we can send data if we want. Now it depends on server logic how it wants to process that request based on the request content (data / body). If the server wants to just execute it like a get request & return something or perform an operation like a POST request & return something. It would have been more simpler.
Why can't there be just a simple HTTP request where we can send data if we want
Because that's not how HTTP works. Each HTTP request has a required request method.
REST leverages this by reusing the semantics of the methods.
Why can't there be one method or no method at all ? Why can't there be just a simple HTTP request where we can send data if we want.
Because describing the semantics of the messages in a consistent way allows generic components to participate in a meaningful way.
For instance, the semantics of a given request are constrained by the common method properties; if the metadata of the message describes itself as idempotent, then generic participants know that, in the event that a response is lost, they can simply repeat the message.
Likewise, if a message is known to be safe, then each of the components know that the message can be dispatched speculatively -- allowing caches to prefetch representations that you may need, communicating to spiders that the content is safe for retrieval and so on.
The HTTP methods support finer grains of distinction; GET vs HEAD, PUT vs DELETE, POST vs PATCH. And of course there are extensions that support other semantics as well.
From the perspective of REST, it doesn't have to be a method per se, so long as the semantics are expressed in such a way that generic components can act on it. HTTP happens to have used methods.
The request method token is the primary source of request semantics; it indicates the purpose for which the client has made this request and what is expected by the client as a successful result.
You are absolutely right that no method at all would be much simpler. But it would also be a lot less powerful: you lose the ability to leverage generic components (like web browsers, caching proxies). The metadata constraints are what make the web possible.
It's all about the semantics of the request. From the RFC 7231:
The request method token is the primary source of request semantics;
it indicates the purpose for which the client has made this request
and what is expected by the client as a successful result.
Here's a brief description of some HTTP methods defined in the RFC 7231 (click the links to check the full method definition):
GET: Transfer a current representation of the target resource.
HEAD: Same as GET, but only transfer the status line and header section.
POST: Perform resource-specific processing on the request payload.
PUT: Replace all current representations of the target resource with the request payload.
DELETE: Remove all current representations of the target resource

Handling write only resources in a HATEOAS based REST api

Let's assume I have a REST resource for my users. If the client requests one specific user with GET, the api returns the following json.
GET https://localhost:8080/api/user/xy
{
"name": "John Smith",
...
"_links": [{
"rel": "self",
"href": "https://localhost:8080/api/user/xy"
},
{
"rel": "changepassword",
"href": "https://localhost:8080/api/user/xy/password"
}]
}
As you can see the api provides a reference (in the _links section) to a resource where the client can change the password. I expect now the client to update the password when sending a PUT request to this reference.
Now my questions:
Is this a good/correct approach to implement a use-case like "change password" in a HATEOAS based REST api? Or is there another/better approach?
What should the server return after changing the password successfully? I would probably expect the status 204 and an empty body.
For sure I don't want to show the user his current password. Therefor my server will return a code 405, if the client is trying to GET the password resource. Is it generally valid to have a "write only" resource in a REST api?
... in a HATEOAS based REST api
First things first, one of the few constraint REST implies is that HATEOAS is already in place and therefore HTTP clients use links to progress its current state. A client not utilizing HATEOAS is not a REST client as well as an API not including links offering a clinet new state-possibilities is not a RESTful API!
Concerning your actual questions, it always depends on how you model certain things. You can use PUT to update the field and then return a 204 No Content response to indicate that this field has no readable content. According to the Spec
If the target
resource does have a current representation and that representation
is successfully modified in accordance with the state of the enclosed
representation, then the origin server MUST send either a 200 (OK) or
a 204 (No Content) response to indicate successful completion of the
request.
returning a 204 No Content status code is eligible.
An other approach could send the old password to the service in order for the service to first check the current password against the provided old one and only then update the password. This might prevent attacks which try to alter the passwords of other users in case you do not use an encrypted connection anyways. In order to achive this validation check however the client is not able to use a simple PUT operation anymore unless you make the old password part of the new state. Here POST is probably better suited as it leaves the semantics to the implementor of the API. This can go as far as to maintain a history of the last n passwords which the new password may not be any of the former ones.
HTTP offers the OPTIONS method a client can use to determine which operations are suitable for certain endpoints. Zac Stewart explained the usefulness of the OPTIONS method in regards to RESTful APIs in a blog post, and also points out the current shortcommings plenty of HTTP server have in regards to the usage of OPTIONS.
Most HTTP frameworks will return a 405 Method Not Allowed response code in cases an endpoint is invoked with an operation that has no implementation by default. At least in Java either in Spring MVC/Rest data or in JAX-RS methods offered at certain endpoints have to be annotated with interfaces that correspond to HTTP methods. Invoking an endpoint with an operation that has now equivalent annotated method will produce a 405 error response automatically, though this might be language and framework dependant.

RESTful - What should a DELETE response body contain

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.

How to send response code in REST services.?

I am developing RESTful Services to CREATE operations. In my use case, it is enough to tell the clients whether the transaction is success or fail. And if fail, we need to send them back error code.
Is it possible to send only these information back without sending xml response or JSON response. If so, how to do it.
We have existing error code in 5 digits, we wont be changing this for this api. If this is not possible.
Will JSON response better than XML response.? We are accepting XML request.
Requesting your comments.
I'm going to assume this service will be called over HTTP, since that's what most people mean when they say "RESTful service."
Generally speaking, most people map "create" type functionality to POST methods (though you can also do it with PUT).
If you just need to indicate that the record was created, the answer is "None of the above" (i.e., you don't need a response body at all). Usually a 201 Created is returned with a Location header which specifies the URL of the newly-created resource. In theory, you could also return a 204 No Content since you don't need to pass anything other than the status code (though this would be more appropriate for a PUT, otherwise there is no way to communicate to the client the identifier of the newly-created resource).
For failures, usually a 400-series error is returned if the request message is bad (i.e., it's the client's fault) and a 500-series error is returned if a system error occurs when processing (i.e., it's the server's fault). If you need to convey additional information in the response body, consider returning a response that uses a media type of something like application/vnd.error which allows you to express context information about where the error occurred.