Caching in JAX-RS for POST requests - rest

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.

Related

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.

REST API How to update client side data after sending request to backend

The frontend/client shows a list of items. Make a request to the backend/ API to change some items. For example, add an item or delete one. How to reflect these changes on the client side after the backend has processed this request successfully?
Examples:
POST request to the backend that adds a new item to the list. The response body contains the added item. Http Status Code 201 CREATED
DELETE request to the backend that removed an item from the list. The response body contains nothing. Http Status Code 204 NO CONTENT
Solutions?
After the request has been processed successfully (client receives 2xx status code) the complete list is going to be fetched again from the backend. Downside: This means we have two requests. First the POST, then a GET.
Return the complete list in the response body of the POST request. This seems strange, because how the client consumes the API affects the behavior of the API.
The client handles the addition or removal of the item itself after it has received a 2xx from the backend. Pro: Only one request. Downside: Problematic if multiple users operate on the data. How to keep everything in sync?
Is there a common pattern of how to handle this in regards to clean API design? I noticed, that a lot of tools make only one request if you change data. Think of Trello or something similar.
How to keep everything in sync?
In REST, you don't. Each client (potentially) has their own local cache. The server includes standardized caching metadata in its responses, to provide the clients with a hint of how often the information may change.
Cache invalidation is standardized, but only the caches that an HTTP request passes through are going to see the triggering requests. So unless your clients are sharing a cache (not likely in the world of HTTPS), somebody is going to have stale data.
The server still has the authoritative copy, of course, and we have standardized conditional requests that give us options when the clients data is too stale.
How to reflect these changes on the client side after the backend has processed this request successfully?
There is a section of the HTTP specification that describes how to identify the representation in an HTTP message. It includes this passage
If the response has a Content-Location header field and its field-value is a reference to the same URI as the effective request URI, the payload is a representation of the resource identified by the effective request URI.
So POST /foo PUT /foo PATCH /foo have a standardized way of announcing that the representation enclosed in the response is a new representation of /foo
There isn't, as far as I can see, any standardized way to communicate side effects; which is to say changes to other resources. We have to fall back on cache invalidation semantics.
For the most part, REST is a bunch of machines pretending to be web browsers talking to a machine that pretends to be a web server.
The REST interface is designed to be efficient for large-grain hypermedia data transfer, optimizing for the common case of the Web, but resulting in an interface that is not optimal for other forms of architectural interaction. -- Fielding, 2000

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

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.

Impact in terms of response time if we only use POST instead of other REST verbs?

I read it in this post that
An operation behind a GET endpoint does not change the target state of
the server therefore the response of a GET endpoint can be cached
resulting in further requests to the same endpoint being returned
faster from the cache
An endpoint behind PUT, POST, PATCH and DELETE changes the target state of the server therefore a successful response out of any of these endpoints can be used to bust the previously cached responses.
So using GET wherever we can, can impact performance(faster responses).
But only using POST instead of other verbs PUT, POST, PATCH and DELETE, can this impact performance(faster responses) in any way or it is just for developers to understand what the API's does?
Thanks.

RESTful Web Api chain Do I use POST or GET?

If I am calling a Web APi service and that service makes various other calls to other services, do I use POST or GET?
To elaborate further, let's say I call Web Api Service One saying 'Do the thing'. Web Api One's job when requested thus, is to GET data from Service Two and POST data to Service Three. Perhaps Service One will then update Service Two. Service One will then respond to caller with any success/failure.
My question again is should I the caller, use POST or GET to Service One?
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 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
In addition to the methods listed above, the RFC 5789 standardized the PATCH HTTP method for performing partial updates to a resource.
POST is commonly seen as a "catch all" method, once the target resource process the request payload according to the resource's own specific semantics.
HTTP methods can be classified as safe and/or idempotent and it must be taken into account when designing an API with on the top of HTTP.
Typically I would only use a variety of HTTP verbs (GET, POST, PUT, DELETE etc) when using a REST API. Then the endpoints are resources in their own right. For example:
/car
So the verbs make sense (are you getting a car? creating one? updating one? removing one?)
But when I am not using a REST API the HTTP verbs tend to have less meaning and I generally only use HTTP POST. Otherwise you hit logical problems like you're experiencing here.
eg
/rentacar
This API models an RPC that may cause many resources to change in many ways. It is not a REST API and so the HTTP Verbs don't really relate.
But in honesty, for RPC (remote procedure calls), people choose between GET and POST by either:
GET for operations that don’t modify anything and POST for other cases.
GET for operations that don’t need too much parameters and POST for other cases.
GET and POST on a random basis or always use POST.
Purists prefer 1. But sometimes you don't know when modifications are going to occur. So, take your pick!