How to handle this response case - java

I have an endpoint to which another team connects. This endpoint returns a response which is irrelevant to the team. It only cares if their input has reached us or not. But we have to do a lot of processing after that. Currently we just take in the request and respond How to handle this scenario. Below is the sample code.
#POST
public Response perform(Request request){
//do something here that takes some time.
return Response.status(Httpstatus.OK).build();
}
What is the best way to make sure that the response goes back to the caller even though the processing keeps going on. I thought about async but wanted to check if there was a better way.

Return a
202 Accepted
The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility for re-sending a status code from an asynchronous operation such as this.
The 202 response is intentionally non-committal. Its purpose is to allow a server to accept a request for some other process (perhaps a batch-oriented process that is only run once per day) without requiring that the user agent's connection to the server persist until the process is completed. The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled.
including a Link where the result will be available.
#POST
public Response perform(Request request){
//TODO attach the request to an asynch background job
//pseudo code!
return Response.status(ACCEPTED)
.location(/* URI where the result will be accessible*/)
.build();
}

Related

REST API - how to deal with post and functional errors

I have a REST service which is a POST to create a user, if the user does not exist, the user is created, and the service returns a 200 with the user in a json format.
Case 1: What if the user exists already, do I return a functionnal exception, so a json containing an error (all of this managed by the error handling of spring boot), and what about the http status code
Some people say to send a 303 or a 409 ... many different answers, and what about the response body in that case?
Case 2: What if in the backend we have let say a rule on the name (like containing a space) which returns an error (space not allowed in a name), same questions, do i have to return a functionnal exception and what about the http status code in this case
Somehow I want the API consumer to know what kind of json structure to handle and i guess the http status code helps for that ?
It all depends on how one interprets the various http status codes and how user friendly do you want your HTTP payload responses to be. Below are few suggestions:
NEW USER CREATED : If its a new user and gets created successfully in the backend then you return http status code 201. This is a technical status code. You can also return a functional status in the response body mentioning "User created"
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201
USER ALREADY EXISTS : If the user already exists, you should respond with http status code 200 with a response payload body mentioning a functional status "User already exists"
USER CREATION FAILED : If the new user rules are not satisfied at the backend service and it throws an error then the http status code of 400 can be used and functional status in response payload of "User creation failed, please conform to the user name rules" https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400
For an API Consumer to know everything about your API's, you may want to provide a API specification document. You may use open API spec(previously known as swagger) https://swagger.io/specification/
Somehow I want the API consumer to know what kind of json structure to handle and i guess the http status code helps for that ?
Not quite.
The HTTP status code is meta data in the transfer documents over a network domain. It communicates the overall semantics of the response (for instance, is the body of the message a representation of a resource, or a representation of an error? is this response cachable? and so on).
For unsafe requests in particular, cache invalidation is sensitive to "non-error status codes". The difference between 303 (non-error status code) and 409 (error status code) can be significant.
The Content-Type header gives you a mechanism to describe the kind (schema) of the message you are returning (ex: application/problem+json).
The way I think about it: the information for your bespoke consumer belongs in the message-body; we lift data from the message-body to the HTTP metadata so that general-purpose components can take advantage of that information (for example, by invalidating cache entries).
So we would normally start by defining the schema and semantics of the message body, and making sure that we have intelligent ways to communicate all of the things we want the caller to know. In other words, we are defining the documents that we pass to the client, and how to extract information from them.
Information that HTTP components need to know get copied from our bespoke document into the standardized forms (status code, headers).
Where things get complicated: the fact that something is an "error" in your domain, that doesn't necessarily mean that it should also be considered to be an "error" in the transfer of documents over a network domain.
A common case: we are using our API to navigate some work through a process; that process has a happy path, and also some exceptional paths that we normally try to avoid (accounts are overdrawn, items are out of stock, etc).
An HTTP request can move work from the happy path to an exception path and still be a "success" in the transfer of documents domain.
The easiest heuristic I know is to think about previously cached copies of responses by the same target URI. If those responses are still re-usable, then you are probably looking at a 4xx status code. If the responses should be invalidated, then you are probably looking at a 2xx or 3xx status code.

How does Resttemplate determine the status code of response before receiving it?

I'm new to Java and found a confusing behaviour related with RestTemplate.
It happened with an API returning large body (~5MB) over a quite slow network condition. The code is like below
ResponseEntity<MyEntity[]> result = restTemplate.exchange(url, HttpMethod.GET, entity, MyEntity[].class);
And also a ClientHttpRequestInterceptor is set to log before and after the request.
The confusing thing is that the after request log is logged only a while after remote server giving the response, and the HTTP Status code can be print in the log.
But the above statement took much more time to finally receive the data. Look inside the thread stack, it was reading data from socket.
I also look inside the resttemplate class and found:
response = request.execute();
handleResponse(url, method, response);
if (responseExtractor != null) {
return responseExtractor.extractData(response);
}
It seems to extractData after the execute().
My doubt is:
How does the client side know the status code even before get all the data? It just extracts necessary fields from the top packets?
Since the server has already sent out the response, where the response data is stored during the process?
It stores the data that it receives from the underlying HTTP in memory.
Client side can know what's the status code because with HTTP you get the headers and status code first before the response body. But this doesn't matter with RestTemplate as it promises to give you an object of ResponseEntity in the end, which contains everything from the http response be it status codex headers or body.
RestTemplate is an abstraction over an HttpClient, most client's give you the option to implement callbacks for separate events like onHeadersReceived(), onStatusReceived() etc. But if you are using RestTemplate this means you don't require such fine grained control.

REST with JAX-RS - Asynchronous call

I saw the below post from "cmd" which was posted couple of years back. And "Wojtek Owczarczyk" was answered this one. I am good with all the answer, except last line.
My Confusion is, If we return immediately with ACCEPTED status. Then, we will lost the track of the request.
So i am planning to implement below steps. Please correct me if i am wrong.
1) As soon as the request hits service api - I will create one Job Id and persist my request detail and send back the client with ACCEPTED status code along with Job id.
2) Then, i will create the new thread for that request to continue with the requested operation.
3) After successful completion of Operation, I will send back the client with all status of the request.
4) Finally, in callbackCompletion register i will remove the job id from my persistence list.
To implement the above logic, i need client to send his listener information along with request (basically URI). This is to update the request status to client back, after processing the request.
REST with JAX-RS - Handling long running operations
This is not how REST is meant to work in my opinion. I would do the following approach instead:
Client makes a request for a long operation
Create a job id and run the job asynchronously
Return the accepted status together with the a URI to request the status for the job. For example: http://.../resources/jobs/1234
The client is now responsible e.g. to poll the URI to get the current status of the job execution.

What is the HTTP status return code for a successful DELETE statement in REST?

I am studying how to Spring handle REST web services (but I don't know if it is a Spring related answer or more generically it is related only to REST concept).
So my doubt is: what exactly is the HTTP status return code for a successful DELETE statement?
Is it the 204 or the 200?
I know that the 200 means that my request was correctly fulfilled but reading online it seems to me that it I expect it after a successful GET returning content and not after a delete.
Somewhere I found that the 204 status is obtained after
successful PUT or DELETE. Is it true? I can't understand, it means that the response is empty, why an empty respons means that the PUT or the DELETE operation are gone succesfull?
There are no strict rules on which HTTP status code is the correct one for each method. It depends on what exactly happened, what information you need to send to the client, etc. I can think of a few examples:
A successful DELETE, with no further information. 204 No Content
A successful DELETE, but you have a warning about related orphan resources that should be deleted too. 200 OK.
You accepted the DELETE request, but it might take a long time and you're going to do it asynchronously. The client should check it later. 202 Accepted.
You accepted the DELETE request, but the resource can't be removed and the URI is instead reset to a default. 205 Reset Content.
An empty response body doesn't mean that a delete is successful, a successful delete (usually) means that the response body is empty.
There's no official status code list for RESTful APIs, but most agree that a 204 is a good response code for a successful delete, as there's usually not a good reason to return a response body after deleting something.
In general, if an operation is successful and the response body is empty return 204. If an operation is successul and the response body is NOT empty, return 200
An empty response doesn't mean the operation was successful, the HTTP error code is supposed to indicate success/failure, and the response body may or may not contain data.
The response body may contain additional information regarding the request, e.g., a specific message to display to the UI, stats or timing info regarding the information, whatever. But it doesn't have to, and the body's purpose is informational/diagnostic if it exists.
2xx represents the request was successful. The xx just allows for you to be more specific about what happened (what the server did or is returning).

Sending GET & POST requests in Java or other without responses

Is it possible to make GET & POST requests in Java or another language such that you don't care about what is returned?
As in just sending the requests but not wanting to receive any responses?
Whether you care about the response or not, it will be sent. The HTTP protocol specifications say that it must be.
If you don't care about the response, your client could just close the connection immediately after sending the request. But the chances are that you do want to know that the request was processed (i.e. the response status) even if you don't want to look at the contents of the response message.
So maybe you could send the request and request body, and read the response status and then close the connection without reading the response body. However, this has a downside. It means that you can't reuse the HTTP connection to make further requests. The next request to the same server has to open a new connection.
You could use anynchronous HTTP requests if you don't care about the responses (that way your worker thread will not have to wait for the response to come back). See http://www.javaworld.com/javaworld/jw-03-2008/jw-03-asynchhttp.html for some details on Asynchronous/Synchronous HTTP queries in Java. Then you can control if the anychronous thread does or does not handle the response (or any failure flagged on the communication) - as long as there were no TCP level failures on the request the connection will still be opened.
You can't control whether or not the server returns a response. Your code is free to ignore any response it receives.
It's pretty hard to not get responses because they're part of the HTTP protocol. but you can certainly ignore the responses.

Categories

Resources