Should I use a POST request to send a retrieval request to my server for a large array of ids? - rest

I read the following posts; however, I still haven't found a conclusive answer to my question.
When do you use POST and when do you use GET?
How should I choose between GET and POST methods in HTML forms?
So why should we use POST instead of GET for posting data? [duplicate]
I want to make a HTTP request to my server to retrieve some data based on an array of ids that I will pass to the server. Since each id will have a length of 23 characters, sending 100 of these ids as query parameters of a GET request will exceed the character length limit of some browsers. Since a standard GET request is not feasible due to URL limits, I have been considering my other options.
Option 1: Use request body of HTTP GET request (not advisable according to following SO thread)
HTTP GET with request body
Option 2: Use body of HTTP POST request to send the array of Ids. This is the method that Dropbox appear to have used for their public-facing API.
I know that POST requests should be reserved for requests that are not idempotent and in my case, I should be using a GET request because the query is idempotent. I also know that REST is purely a guideline and since this API will only be consumed by me, I can do whatever I like; however, I thought I'd get a second opinion on the matter before I commit to any decision.
So, what should I do in my situation? Are there better alternatives that I have yet to discover and is there anything I should consider if I do use a POST request?

So, what should I do in my situation?
First step is to review the HTTP Method Registry, which is defined within RFC 7231
Additional methods, outside the scope of this specification, have been standardized for use in HTTP. All such methods ought to be registered within the "Hypertext Transfer Protocol (HTTP) Method Registry" maintained by IANA
The registry is currently here: https://www.iana.org/assignments/http-methods/http-methods.xhtml
So you can review methods that have already been standardized, to see if any of them have matching semantics.
In your case, you are trying to communicate a query with a message-body. As a rule, queries are not merely idempotent but also safe.
A quick skim of the registry might lead you to consider SEARCH
SEARCH is a safe method; it does not have any significance other than executing a query and returning a query result
That looks like a good option, until you read through the specification carefully, and notice the constraints relating the message body. In short, WebDAV probably isn't what you want.
But maybe something else is a fit.
A second option is to consider your search idiom to be a protocol. You POST (or PUT, or PATCH) the ids to the server to create a resource, and then GET a representation of that resource when you want the results.
By itself, that's not quite the single call and response that you want. What it does do is set you up to be thinking about how to be returning a representation of query result resource. In particular, you can use Content-Location to communicate to intermediaries that the response body is in fact the representation of a resource.
I know that POST requests should be reserved for requests that are not idempotent
That's not quite right. When making requests that align with the semantics of another method, we prefer using that other method so that intermediate components can take advantage of the semantics: an idempotent request can be tried, a safe request can be pre-fetched, and so on. Because POST doesn't offer those guarantees, clients cannot take advantage of them even if they happen to apply.
Depending on how you need to manage the origin servers URI namespace, you could use PUT -- conceptually, the query and the results are dual to one another, so can be thought of as two different representations of the same thing. You might manage this with media types - one for the request, a different one for the response.
That gets you back idempotent, but it doesn't get you safe.
I suspect safe requests with payloads are always going to be a problem; the Vary header in HTTP doesn't have an affordance to allow the server to announce that the returned representation depends on the request body (in part because GET isn't supposed to have a request body), so it's going to be difficult for an intermediate component to understand the caching implications of the request body.
I did come across another alternative method from another SO thread, which was to tunnel a GET request using POST/PUT method by adding the X-HTTP-Method-Override request header. Do you think its a legitimate solution to my question?
No, I don't think it solves your problem at all. X-HTTP-Method-Override (and its variant spellings) are for method tunneling, not method-override-the-specification-ing. X-HTTP-Method-Override: GET tells the server that the payload has no defined semantics, which puts you back into the same boat as just using a GET request.

Related

HTTP method for both sending and returning information

I'm building a web application that needs to process some information on a server. There is no database involved, the server (using Flask) just needs to receive some (complex) information, process it, and send back the result.
My question is which HTTP method is most suitable here (if any). When I read about HTTP methods, they are usually explained in terms of a REST api, where a GET request is used to retrieve data from the server and a POST request is used to create new data on the server. In my case however, I don't need to store any information on the server. A GET request doesn't seem suitable here, as the information sent to the server is rather complex, and can't be easily encoded in the URL. I think a POST request should work here, as I can send the data in JSON format, but the specifications say POST should be used when you want to create something on the server, and a response should only contain a success message and/or location.
Am I missing something here? Should I use something different like WebSocket, or is a POST request fine here, although it doesn't abide by the REST principles?
Thanks in advance.
the specifications say POST should be used when you want to create something on the server
No, they don't. A lot of people say that, but the specification is not so restrictive.
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics
Here's how Roy Fielding explained it in 2009:
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”
Yes, POST isn't ideal - the semantics of POST are neither safe nor idempotent, and your particular case would benefit from communicating those properties to general purpose components.
But it is good enough, until the work is done to standardize the semantics of a new method token that better handles this case.
We use POST method to send data to the server. What the server does with the data is encoded in the server logic.
As a client if you want to just send data to server use POST.

Are PUT and DELETE HTTP methods indispensable just because of their idempotency property?

I have a REST API and I want to handle all HTTP requests via POST request.
Is there any performance or other kind of issue in using just POST to perform all CRUD operations requested by a user, which sends a JSON containing some data and the operation to be performed?
Technically, the HTML used in the Web only supports GET and POST and this is more or less the reference implementation of a REST architecture.
So, while this is possible I wouldn't advocate for something like that as the idempotency property of PUT and DELETE provide some other benefits in case of network issues where a client can automatically resend the request regardless whether the initial request, whose response might have just got lost mid-way, actually performed its task or not. The result should always be an updated/created resource or a removed URI mapping to the actual resource (or even a removal of the actual resource) as DELETE technically just removes the URI mapping.
In regards to put some operations in the payload, it depends. This actually sounds very RPCy to me, similar to SOAP i.e. If the operation however is defined by a well-defined media-type, like in the JSON Patch case, I guess this is not wrong. Similar to the Web, however, a server should use some resource that is able to teach a client on how to build up a request, like HTML does with forms. This will not only teach the client on what fields the server supports for the target resource but also where to send the request to as well as the media-type and HTTP operation to use, which might be fixed to POST as in the HTML case.

GET or POST? Action not destructive, a lot of parameters, no need to cache

I am designing an API endpoint that runs a simulation, and returns the result.
The specific simulation that is run depends on many parameters.
There are no side effects. Nothing destructive (creating, updating, deleting) is happening.
I don't desire to cache the parameters in the query string of the URL for the user to save, or click refresh.
Should this endpoint accept GET requests, or POST requests?
The query string isn't big enough to hold all the parameters. And apparently you aren't supposed to send a payload along with GET requests.
There are no destructive side effects (no side effects at all). So POST doesn't seem appropriate either.
What should I do?
Should this endpoint accept GET requests, or POST requests?
I've got some good news for you. REST doesn't care.
Riddle: how would you provide this service on a web site?
You'd probably have some landing page of general interest, and onto that page you would add a link "click here to try the simulator!" When the consumer followed that link, you would provide a representation of a form describing the parameters required for the simulation, with an identifier for an endpoint and an action. The consumer would submit the filled out form, dispatching to your endpoint a representation of the simulator parameters.
A hypermedia API works the same way; the client shouldn't need to know the endpoint, or what method to use. What it needs to know is how to obtain that information from the representation of the form.
If you have a hypermedia API, you can change endpoints, or switch back and forth between http methods, without requiring that the client be updated to match.
There are no destructive side effects (no side effects at all). So POST doesn't seem appropriate either.
I've got more good news for you. Using POST is fine. The current authority for using POST isn't stack overflow, but RFC-7231
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics. For example, POST is used for the following functions (among others):
Providing a block of data, such as the fields entered into an HTML form, to a data-handling process
Perfect. It's not cacheable, unless you explicitly make it so. It contains facilities for redirecting the user to a cacheable representation of the data, for cases when that makes sense.
What POST doesn't do is communicate to the browser, or the intermediary components, that it is safe to retry a lost message.
Here's what Fielding had to say about this in 2009
It isn’t RESTful to use POST for information retrieval when that information corresponds to a potential resource, because that usage prevents safe reusability and the network-effect of having a URI.
POST only becomes an issue when it is used in a situation for which some other method is ideally suited: e.g., retrieval of information that should be a representation of some resource (GET), complete replacement of a representation (PUT), or any of the other standardized methods that tell intermediaries something more valuable than “this may change something.” The other methods are more valuable to intermediaries because they say something about how failures can be automatically handled and how intermediate caches can optimize their behavior. POST does not have those characteristics, but that doesn’t mean we can live without it. POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”
HTTP doesn't specify a method for safe operations that include a payload. It
does specify an idempotent method that includes a payload; PUT. Using PUT is unusual in so far as it doesn't really align with the usual understanding of "Create" or "Update", but so long as you are careful about identifiers, I think that it is valid.
Fielding, writing in 2006:
PUT does not mean store. I must have repeated that a million times in webdav and related lists. HTTP defines the intended semantics of the communication -- the expectations of each party. The protocol does not define how either side fulfills those expectations, and it makes damn sure it doesn't prevent a server from having absolute authority over its own resources.
I understand this to mean:
The server is not constrained to track the state of the resource as is; it can use an output representation, rather than an input representation
The server is not constrained on what access to allow; the resource can be write only. Or getting the resource can provide its input representation again.
The server is not constrained on the permanence of the change; "we successfully processed your request (but then immediately reverted the outcome)" is perfectly valid.
From RFC 7231:
A successful response only implies that the user agent's intent was achieved at the time of its processing by the origin server.
In addition, the definition of the 200 status code gives you some room
For the methods defined by this specification, the intended meaning of the payload can be summarized as:
GET a representation of the target resource
PUT, DELETE a representation of the status of the action;
So I think it's an option that may, upon detailed review, be more suitable to your particular circumstances than POST or GET.
I believe with something like this you would want to have aPOST request and return the user something in the Response in JSON or XML. Im using an API for a site now that sends a POST and I get the data out of the Response, and I to have a lot of parameters I'm passing.
First, this API endpoint should be refactored and simplified. HTTP request with a lot of parameters should be avoided, no matter it is a GET or POST or something else. Request with a lot of parameters means very tight coupling between 2 modules -- client side have to assemble very carefully to meet the requirement of server. Also, request with a lot of parameters brings cost on documentation and training.
That said, it has to be a POST if a lot of parameters cannot be avoided. The reason is: although it should be a GET (semantically), GET is not feasible in this situation -- the request with all parameters exceeds the maximum limit of query string. Browser may truncate the query string and break the request.
In summary, it is not a question about what I should do, it is a question about what I have to do, unless the API endpoint is optimized.

Use POST instead of PUT REST [duplicate]

This question already has answers here:
What is the difference between POST and PUT in HTTP?
(41 answers)
Closed 1 year ago.
POST:- is used to create and update resources
PUT:- is used to update existing resources
Can I use POST instead of PUT method? and If I use POST method over PUT method, what will be disadvantages?
If POST can do work of PUT method, why PUT method is required?
Can I use POST instead of PUT method?
Yes, you can. HTML forms, for example, use POST for all writes.
If POST can do work of PUT method, why PUT method is required?
It didn't use to be. In HTTP/1.0, the specified methods were HEAD, GET, and POST. PUT was relegated to Appendix D: Additional Features.
If I use POST method over PUT method, what will be disadvantages?
PUT is idempotent. POST is not.
A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request....
the idempotent property only applies to what has been requested by the user; a server is free to log each request separately, retain a revision control history, or implement other non-idempotent side effects for each idempotent request.
Idempotent methods are distinguished because the request can be repeated automatically if a communication failure occurs before the client is able to read the server's response. For example, if a client sends a PUT request and the underlying connection is closed before any response is received, then the client can establish a new connection and retry the idempotent request. It knows that repeating the request will have the same intended effect, even if the original request succeeded, though the response might differ.
What this means is that for PUT, the client can use at-least-once-delivery of the request; repeatedly sending the same PUT message across an unreliable network until a response is received.
(This guarantee is provided by the server, communicated by the fact that a given resource accepts PUT messages. It's not free, you need to make sure that the server handles the messages correctly.)
Notice that it isn't just the client that is aware of this guarantee, but also all intermediate components (proxies) that can see the request message -- the proxy doesn't need to go back to the browser to ask the user if it is safe to retry the message -- the PUT method says the server is providing the guarantee that it is.
A POST request says "Here is some data, parse it using the handler at the specified URL, and then do something useful with it"
A PUT request says "Here is some data and a URL. If anyone makes a GET request for that URL, give them this data."
They do distinctly different things.
You could achieve the same end as a PUT request using a POST request, but the semantics for how to process the PUT request are predefined and standard.
The main difference is POST does not guarantee idempotent, and PUT must guarantee it.
Meaning, suppose you update a record to increment it, then you cannot use POST. Because each time a user makes that update the record will be different, and so the user cannot just go on trying again and again and expect the same result. With PUT update, the user is allowed to keep trying the request many times and is guaranteed that the final record and response will always be the same no matter how many times the user makes the update request.
Mostly people don’t want to give this kind of guarantee so they just use POST, which is not idempotent. But say you're not incrementing anything just putting the same file, user can expect exact same fileId and response even if he repeatedly calls, you can use PUT.
For idempotent things, you’re also allowed to do insert with PUT. So both POST/PUT can be used for insert/update (both submit data). It’s up to the dev how they want to use - some like to map CRUD to the methods - others just POST or PUT for everything depending on idempotence.
POST and PUT can help consumers of your REST api understand what is happening in your API. For example you may require some kind of token on PUT (aka update) to help ensure that the entity being updated hasn't been changed since it was read. POST might fail differently when the entity already exists vs. PUT failing only if it has been changed or failing if it DOES NOT exist. Really sounds like you need to look at some existing REST APIs and get an idea of how they work.
I believe it is up to the developer which one to use.
Lets say you are creating a record. If your ID field is empty means it is a create request. If ID is provided, then it is an update request.
Developers can distinguish it. I understand idempotent requests will guarantee that result will be same but same for the POST method if you are sending ID = 1.
We can always update record even you send the same request 1000 times.
You can also read a post here which elaborates on this point.

GET vs POST in REST Web Service

I'm in the process of developing a REST service that allows a user to claim their listing based on a couple of pieces of information that appear on their invoice (invoice number and billing zip).
I've read countless articles and Stack Overflow questions about when to use GET and when to use POST. Overall, the common consensus is that GET should be used for idempotent operations and POST should be used for operations that create something on the server side. However, this article:
http://blog.teamtreehouse.com/the-definitive-guide-to-get-vs-post
has caused me to question using GET for this particular scenario, simply because of the fact that I'm using these 2 pieces of information as a mechanism to validate the identity of the user. I'm not updating anything on the server using this particular method call, but I also don't necessarily want to expose the information in the URL.
This is an internal web service and only the front-end that calls the service is publicly exposed, so I don't have to worry about the URL showing up in a user's browser history. My only concern would be the unlikely event that someone gain server log access, in which case, I'd have bigger problems.
I'm leaning toward POST for security reasons; however, GET feels like the correct method due to the fact that the request is idempotent. What is the recommended method in this case?
Independently of POST vs GET, I would recommend NOT basing your security as something as simple as a zip code and an invoice number. I would bet on the fact that invoice numbers are sequential (or close), and there aren't that many zip codes around - voila, I got full access to your listings.
If you're using another authentication method (typically in HTTP header), then you're good - it doesn't matter if you have an invoice number if the URL, so might as well use GET.
If you're not, then I guess POST isn't as bad as GET in term of exposing confidential content.
There isn't really any added security in a POST vs a GET. Sure, the request isn't in the URL, but it's REST we are talking about here, and the URL wouldn't be seen by a human anyway.
You question starts with some bad presumptions. Firstly, GET is not just for any old idempotent operation, it is for GETting resources from the server; it just happens that doing so should be side effect free. Secondly, the URL is not the only way for a GET request to send data to the server, you can use a payload with a GET request (at least as far as HTTP is concerned, some implementations are bad and don't support this or make it hard). Third, as pointed out, you have chosen some terrible data fields to secure your access. Finally, you are using a plain text protocol any way, so what neither method really offers and better security.
You should use the the verb that best describes what you are doing, you are getting some information from the server, so use GET. Use some proper security, such as basic HTTPS encryption. If you want to avoid these fields 'clogging' up the URL, you can send data in the payload of the request, something like:
GET /listings HTTP/1.1
Content-Type = application/json
{ "zip" : "IN0N0USZ1PC0D35",
"invoice" : "54859081145" }