How to make REST call asynchronous in Java - java

I have REST calls between two microservices, one of the call is taking more than 15 mins of time to complete. We have company's own private cloud implementation which is terminating any open connection kept for more than 15 mins.
We are looking for some asynchronous rest call implementation, where service A will trigger the rest call to service B and forget and service B will notify when the response is ready to be served.
Is there any widely used technique/API for such scenario? I was not able to find any thing concrete on this front.

You could use Polling. Something like this :
Service A triggers a Rest call to Service B which returns an OK response. Then in each 1 minute service A make another API request to another endpoint in Service B which would return status of the previous request until the process is completed or for may be a certain point of time. Now when the 2nd request send the status as success you can mark the process as completed.

Instead of creating the actual resources, create a temporary one. Instead of returning a 201 (Created) HTTP response, you can issue a 202 (Accepted) response code. This informs the client that the request has been accepted and understood by the server, but the resource is not (yet) created. Send the temporary resource inside the Location header.
Request:
POST /blogs HTTP/1.1
<xml>
blogdata
</xml>
Response:
HTTP/1.1 202 Accepted
Location: /queue/12345
This location can store information about the status of the actual resource: an ETA on when it will be created, what is currently being done or processed.
When the actual resource has been created, the temporary resources can return a 303 (See other) response. The location header returns the URI to the definitive resource. A client can either DELETE the temporary resource, or the server can expire this resource and return a 410 (Gone) later on.
Source: https://restcookbook.com/Resources/asynchroneous-operations/

Related

Spring REST - Proper PUT functionality when resource does not already exist

I am building a REST API using Spring and implementing the PUT functionality. I am trying to handle the scenario in which the client tries to PUT to a uri where the resource does not already exist. In this scenario, per the PUT spec, a new resource should be created at that ID. However because of the ID generation strategy I am using (#GeneratedValue(strategy = GenerationType.IDENTITY)), I cannot create resources with IDs out of sequence. The database must use the next available value. However, according to the w3 spec on PUT...
If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.
If the server desires that the request be applied to a different URI, it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request.
In this case, I can do neither of these. I cannot create a new resource at the existing URI due to the ID generation restrictions, and I cannot send a 301 Moved Permanently response because according to How do I know the id before saving an object in jpa it is impossible to know the next ID in a sequence before actually persisting the object. So I would have no way of telling the client what URI to redirect to in order to properly create the new resource.
I would imagine this problem has been solved many times over because it is the standard PUT functionality, yet I am having trouble finding any other people who have tried to do this. It seems most people just ignore the "create new resource" part of PUT, and simply use it as update only.
What I want to do is just go ahead and create the new resource, and then send the 301 Moved Permanently to redirect the client to the true location of the created resource - but as we see above, this violates the definition of PUT.
Is there a spring-y way to solve this problem? Or is the problem unsolved, and the true standard practice is to simply not allow creation of new resources via PUT?
If the server cant processes the request due to an error in the request, just return a 400.
400 Bad Request -
The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, size too large, invalid request message framing, or deceptive request routing).

How to read websocket response code through automation scripts

Suppose I have a resource that is hosted on a websocket server, and I wish to validate the response status code 101, after the connection is upgraded, how and which libraries to use.
Im currently looking at jayway response library, when I connect to a websocket resource, initially it sends a 200 and then upgrades to 101. So code returns 200, I would like to know how this library can be used for websocket validation.
Sample code is :
String response =given().get()("https://www.ws.com:444/examples/websocket/snake.xhtml")
.getResponse().asString();
This returns a 200, but does not return the next response. I might sound a little rusty here, would appreciate if you folks have any idea how to extend it to get status 101 or if you have any other suggestions.
Also, this requirement needs to be extended to handle redirection 30x status codes as well, assume a resource is protected behind an access gateway, when a request comes for this protected resource, the gateway forwards it to identity store for verifying the user, at this time a 302 is returned, once verified, request is sent back to access gateway from where user is able to access websocket resource.

PUT response code with 204

My PUT and POST are same, so I am using PUT operation. Here I need to send response body data when PUT successful e.g. either new data insert into Cassandra or update existing record.
So, what response code should I use in this case.. code 204 I am using for successful PUT with response body, but it automatic convert into 200 code while testing with POSTMAN. so what should I use here.
According to this:
If the target resource does not have a current representation and the
PUT successfully creates one, then the origin server MUST inform the
user agent by sending a 201 (Created) response. 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.
Based on this (and agreeing with Hank), if you have an entity with your response, you should use 201.

JAX WS async client: capture WS-Addressing 202 accepted

I have to invoke several webservices using WS-Addressing.
When invoking a webservice, the ReplyTo is set to a callback endpoint implemented by me.
The client is generated from the target WSDL using async with
<enableAsyncMapping>true</enableAsyncMapping>
which generates the Async version for each webservice with the following signature:
javax.xml.ws.Response<SampleWebServiceOutput> sampleWebService(SampleWebServiceInput input)
When invoking sampleWebService like,
Response<SampleWebServiceOutput> response = clientWsPort.sampleWebService(input);
if the request is sucessful, the server will return 202 Accepted however I can't figure out how to get it.
If I use response.get(), it will block forever since the response is sent to my callback url (WSA-Addressing Reply To)
Any clues how to know for sure if the server successfully accepted the request ?
Thank you.
Apparently the response returned when you set a different reply-to address results in a null response, which could explain why it is hanging when you call response.get().
The recommended solution is to use something like getResponseContext(), which is called from the binding.

Get response header OkHttp

I need to check response header of HTTP request using OkHTTP library. before loading data I need to check it's last update time. The problem in that that the response body is about 2 MB so I need to get only Last-Modified header. Is it possible to load only response header without response body to increase the speed of the program`s RESTful actions?
You can send a HTTP HEAD request which only retrieves the headers. You only need to check if your server application supports HEAD requests.
The HEAD method is identical to GET except that the server MUST NOT
return a message-body in the response. The metainformation contained
in the HTTP headers in response to a HEAD request SHOULD be identical
to the information sent in response to a GET request. This method can
be used for obtaining metainformation about the entity implied by the
request without transferring the entity-body itself. This method is
often used for testing hypertext links for validity, accessibility,
and recent modification. (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)
Example for OkHttp:
String url = ...
Request request = new Request.Builder().url(url).head().build();
The response body is streamed, so you can make the regular request, read the headers, and then decide whether or not to consume the body. If you don’t want the body, you can close() it without much waste.
There is a slight cost to the server to serve a response that might be abandoned. But the overall cost will be lower than making a HEAD and then a GET request unless you expect abandon a significant fraction (say > 90%) of requests.

Categories