Retrieve data from webservice, with side effects - what method to use - rest

I am in the process of writing a webservice that sends data to the client, but it has side effects.
This webservice will be called periodically, and any data that is being sent to the client will be marked as such and will not be sent again.
The client is 100% stateless, I can't expect it to send something like a timestamp of the last request. The administration of state lies with the web service.
I am a firm believer that GET requests must be idempotent, so I cannot use that as the method. POST and PUT on the other hand are used to create/update resources, which is not the case here.
What http method would you choose and why?

I finally went with POST.
Mostly the argument
If the client can not be expected to implement basic HTTP measures such as a conditional GET with an If-Modified-Since or sth. like that ... then the other end is probably not the one to be puristic about HTTP either.
is what persuaded me.

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.

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.

How can I implement a RESTful Progress Indicator?

I want my API to be be RESTful
Let say I have started a long running Task with POST and now want to be informed about the progress?
What is the idiomatic REST way to do this?
Poll with GET every 10 seconds?
The response to your
POST /new/long/running/task
should include a Location header. That header will point to an endpoint the client can hit to find out the status of the task. I would suggest your response look something like:
Location: http://my.server/task-status/15
{
"self": "/task-status/15",
"status": "running",
"expectedFinishedAt": <timestamp>
}
Then your client doesn't have to ping arbitrarily, because the server is giving it a hint as to when to check back. Later GETs to /task-status/15 will return updated timestamps. This saves you from having to blindly poll the server. Of course, this works much better if the server has some idea as to how long it will take to finish processing the task.
The way REST works, or rather the mechanism it uses - the HTTPS GET/POST/PUT/DELETE etc. doesn't provide a mechanism to have an event-driven mechanism where the server could send the data to the client. Though, it is theoretically be possible to have client/server functionality in both your server and in your client - though I wouldn't personally endorse this design. So having some sort of a submit API - POST/PUT and then a status query mechanism - GET would do the job.
The client should be the one giving you that information, showing you how many bytes have been sent already to the server. The server should not care about a partially uploaded resource.
That put aside, you will return a "Location" header indicating where is the resource once is created, but not earlier. I mean, when you POST you don´t know which is going to be the address of the resource (that is indicated later in the Location header), so there is no reasonable way of providing an URL to check the status of the upload, because there is no reasonable way of identifying it till is done (you may try crazy things, but it is not recommendable).
Again, the client should give you that feedback, not the server.

Caching in JAX-RS for POST requests

I was thinking of leveraging the cachecontrol option in JAX-RS.
But all i know and fully understand is, its used in GET and PUT requests.
Has anyone ever tried using it for a POST request?
I am building a RESTful webservice that caters to client's requests. It internally forwards client's request to another component and dumps the response back to the client. The response is same for identical requests.
How can i use caching to sometimes directly respond from the cache instead of forwarding/receiving response from the the internal component?
I can't use a database or nosql dDB for caching request/response. I want something in memory that is lost once application restarts.
HTTP has methods that are safe or unsafe, and methods that are idempotent or not idempotet. See the HTTP spec:
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.
You can GET, PUT, or DELETE a Resources as often as you like, the result will be the same, no matter how often you do it.
As you see, POST is not idempotet. It makes a difference to POST a request to a Resource once, twice, or more often. That's because the semantics of POST is to create something below the Resource you POST to.
Because of all this, it makes no sense to cache the result of a POST request.