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

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

Related

Recommended or not: Sending a JSON body via POST HTTP Request without modification

Is it recommended to send a JSON body via a POST HTTP Request which doesn't modify anything?
Based on the link below, a Get request is not recommended to have a body. Thus, the other way is the one above.
HTTP GET with request body
Example:
Get the list of users, or anything for that matter based on parameters.
Http GET example.com/users
Body
{
name:"John",
age:1,
... long list of parameters
}
Is it recommended to send a JSON body via a POST HTTP Request which doesn't modify anything?
The rule is that POST is the default; it should be used unless there is something better.
For a request with "effectively read only" semantics, you want to use GET instead of POST... if it works. The challenge can be those cases where the request-target (aka: the URI) gets long enough that you start running into 414 URI Too Long responses. If your identifier is long enough that general purpose components refuse to pass the request along, then it is not something better, and you fall back to POST.
An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain. (HTTP Semantics, 9.3.1)
In other words, introducing a private agreement to include content in a GET request trades away inter-op, which - if you want "web scale" - is not a winning trade. So GET-with-a-body is not better, and you fall back to POST.
The HTTP working group has been working on semantics for a new "effectively-read-only-with-a-body" method token, which could prove to be an alternative for requests where you need to include a bunch of information in the body because it is too long to encode it into the URI. But we don't have a standard for that today, which means that it is not something better, and you fall back to POST.

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!

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.

Requesting RESTful GET with meaningful Body? Standards not clear

We found ourselves in a dead end when trying to follow standards as we need to build a request that should be a GET and should have a meaning Body.
The request just wants to retrieve some data, no modification inside the database, just getting some data. But at the same time we need to send an array of ids for the objects we want to retrieve, and no, these objects can't be indexed in any way so we really need to send the list of ids or alternatively make 100 requests to the server to get them one by one. That's not gonna happen.
We could also add the list to the URL, but we can't be sure the URL won't end up being too long if the list of ids were to be too big. So to ensure the system doesn't fail we want to use the Body.
I read that a GET can have a Body, but only if it isn't meaningful:
HTTP GET with request body
Yes. In other words, any HTTP request message is allowed to contain a message body, and thus must parse messages with that in
mind. Server semantics for GET, however, are restricted such that a
body, if any, has no semantic meaning to the request. The requirements
on parsing are separate from the requirements on method semantics.
So, yes, you can send a body with GET, and no, it is never useful to do so.
This is part of the layered design of HTTP/1.1 that will become clear again once the spec is partitioned (work in progress).
....Roy
But our Body IS meaningful, which takes us to have to decide between unfollowing HTTP standards or unfollowing REST standards.
Is there any alternative to that? (It's not that this blocks us but I would like to know the answer).
Thank you very much.
you should consider changing your request to POST method.
As I understand it, there are three potential issues with a GET with request body: (link to blog)
Not all servers will support this.
Not all tools will support this (Swagger, POSTMAN added support this year: https://github.com/postmanlabs/postman-app-support/issues/131)
There is not yet a consensus on GET with request body. (For example, is Dropbox still using a POST)
so you'll have problems process the body with GET

HTTP POST with URL query parameters -- good idea or not?

I'm designing an API to go over HTTP and I am wondering if using the HTTP POST command, but with URL query parameters only and no request body, is a good way to go.
Considerations:
"Good Web design" requires non-idempotent actions to be sent via POST. This is a non-idempotent action.
It is easier to develop and debug this app when the request parameters are present in the URL.
The API is not intended for widespread use.
It seems like making a POST request with no body will take a bit more work, e.g. a Content-Length: 0 header must be explicitly added.
It also seems to me that a POST with no body is a bit counter to most developer's and HTTP frameworks' expectations.
Are there any more pitfalls or advantages to sending parameters on a POST request via the URL query rather than the request body?
Edit: The reason this is under consideration is that the operations are not idempotent and have side effects other than retrieval. See the HTTP spec:
In particular, the convention has been
established that the GET and HEAD
methods SHOULD NOT have the
significance of taking an action other
than retrieval. These methods ought to
be considered "safe". This allows user
agents to represent other methods,
such as POST, PUT and DELETE, in a
special way, so that the user is made
aware of the fact that a possibly
unsafe action is being requested.
...
Methods can also have the property of
"idempotence" in that (aside from
error or expiration issues) the
side-effects of N > 0 identical
requests is the same as for a single
request. The methods GET, HEAD, PUT
and DELETE share this property. Also,
the methods OPTIONS and TRACE SHOULD
NOT have side effects, and so are
inherently idempotent.
If your action is not idempotent, then you MUST use POST. If you don't, you're just asking for trouble down the line. GET, PUT and DELETE methods are required to be idempotent. Imagine what would happen in your application if the client was pre-fetching every possible GET request for your service – if this would cause side effects visible to the client, then something's wrong.
I agree that sending a POST with a query string but without a body seems odd, but I think it can be appropriate in some situations.
Think of the query part of a URL as a command to the resource to limit the scope of the current request. Typically, query strings are used to sort or filter a GET request (like ?page=1&sort=title) but I suppose it makes sense on a POST to also limit the scope (perhaps like ?action=delete&id=5).
Everyone is right: stick with POST for non-idempotent requests.
What about using both an URI query string and request content? Well it's valid HTTP (see note 1), so why not?!
It is also perfectly logical: URLs, including their query string part, are for locating resources. Whereas HTTP method verbs (POST - and its optional request content) are for specifying actions, or what to do with resources. Those should be orthogonal concerns. (But, they are not beautifully orthogonal concerns for the special case of ContentType=application/x-www-form-urlencoded, see note 2 below.)
Note 1: HTTP specification (1.1) does not state that query parameters and content are mutually exclusive for a HTTP server that accepts POST or PUT requests. So any server is free to accept both. I.e. if you write the server there's nothing to stop you choosing to accept both (except maybe an inflexible framework). Generally, the server can interpret query strings according to whatever rules it wants. It can even interpret them with conditional logic that refers to other headers like Content-Type too, which leads to Note 2:
Note 2: if a web browser is the primary way people are accessing your web application, and application/x-www-form-urlencoded is the Content-Type they are posting, then you should follow the rules for that Content-Type. And the rules for application/x-www-form-urlencoded are much more specific (and frankly, unusual): in this case you must interpret the URI as a set of parameters, and not a resource location. [This is the same point of usefulness Powerlord raised; that it may be hard to use web forms to POST content to your server. Just explained a little differently.]
Note 3: what are query strings originally for? RFC 3986 defines HTTP query strings as an URI part that works as a non-hierarchical way of locating a resource.
In case readers asking this question wish to ask what is good RESTful architecture: the RESTful architecture pattern doesn't require URI schemes to work a specific way. RESTful architecture concerns itself with other properties of the system, like cacheability of resources, the design of the resources themselves (their behavior, capabilities, and representations), and whether idempotence is satisfied. Or in other words, achieving a design which is highly compatible with HTTP protocol and its set of HTTP method verbs. :-) (In other words, RESTful architecture is not very presciptive with how the resources are located.)
Final note: sometimes query parameters get used for yet other things, which are neither locating resources nor encoding content. Ever seen a query parameter like 'PUT=true' or 'POST=true'? These are workarounds for browsers that don't allow you to use PUT and POST methods. While such parameters are seen as part of the URL query string (on the wire), I argue that they are not part of the URL's query in spirit.
You want reasons? Here's one:
A web form can't be used to send a request to a page that uses a mix of GET and POST. If you set the form's method to GET, all the parameters are in the query string. If you set the form's method to POST, all the parameters are in the request body.
Source: HTML 4.01 standard, section 17.13 Form Submission
From a programmatic standpoint, for the client it's packaging up parameters and appending them onto the url and conducting a POST vs. a GET. On the server-side, it's evaluating inbound parameters from the querystring instead of the posted bytes. Basically, it's a wash.
Where there could be advantages/disadvantages might be in how specific client platforms work with POST and GET routines in their networking stack, as well as how the web server deals with those requests. Depending on your implementation, one approach may be more efficient than the other. Knowing that would guide your decision here.
Nonetheless, from a programmer's perspective, I prefer allowing either a POST with all parameters in the body, or a GET with all params on the url, and explicitly ignoring url parameters with any POST request. It avoids confusion.
I would think it could still be quite RESTful to have query arguments that identify the resource on the URL while keeping the content payload confined to the POST body. This would seem to separate the considerations of "What am I sending?" versus "Who am I sending it to?".
The REST camp have some guiding principles that we can use to standardize the way we use HTTP verbs. This is helpful when building RESTful API's as you are doing.
In a nutshell:
GET should be Read Only i.e. have no effect on server state.
POST is used to create a resource on the server.
PUT is used to update or create a resource.
DELETE is used to delete a resource.
In other words, if your API action changes the server state, REST advises us to use POST/PUT/DELETE, but not GET.
User agents usually understand that doing multiple POSTs is bad and will warn against it, because the intent of POST is to alter server state (eg. pay for goods at checkout), and you probably don't want to do that twice!
Compare to a GET which you can do as often as you like (idempotent).
I find it perfectly acceptable to use query parameters on a POST end-point if they refer to an already-existing resource that must be updated through the POST end-point (not created).
For example:
POST /user_settings?user_id=4
{
"use_safe_mode": 1
}
The POST above has a query parameter referring to an existing resource, mirroring the GET end-point definition to get the same resource.
The body parameter defines how to update the existing resource.
Edited:
I prefer this to having the path of the end-point to point directly to the already-existing recourse, like some suggest to do, like so:
POST /user_settings/4
{
...
}
The reason is three-fold:
I find it has better readability, since the query parameters are named, like "user_id" in the above, in stead of just "4".
Usually, there is also a GET endpoint to get the same resource. In that case the path of the end-point and the query parameters will be the same and I like that symmetry.
I find the nesting can become cumbersome and difficult to read in case multiple parameters are needed to define the already-existing resource:
POST /user_settings/{user_id}/{which_settings_id}/{xyz}/{abc}/ ...
{
...
}