Web service long implementation period

1

I'm creating a webservice that queries in a DW these queries because they have aggregation functions and everything takes a bit more time than normal (something around 2 - 5 minutes), but the client does not wait for this query terminating it understands how to timeout the response due to time. I would like to know if it has how I inform the client that the query will take and how to do it, below the technologies I am using.

javax, restful webservice,

My code is something like this:

@GET
@Path("/QtdeVendasNoPeriodo/{dtInicio}/{dtFim}")
@Produces("application/json; charset=UTF-8;")
public ArrayList<DetalhesVenda> QtdeVendasNoPeriodo(@PathParam("dtInicio") Date dtInicio,@PathParam("dtFim") Date dtFim){

// Logica do metodo
}

Until the webservice is tested, this is impossible because it takes time and the applications I know to test also understand how to timeout the response temp.

    
asked by anonymous 22.06.2017 / 21:01

1 answer

1

For the customer to know how long it will take, you need to submit a response. This type of problem can be adequately addressed using an asynchronous approach. There are advantages to doing this. For example, in case of high demand, you can queue requests to your DW and do not leave "locked" threads on your server. In addition, customers do not need to change the connection timeouts to their REST service. Of course the implementation complexity increases a bit, but it pays to have a more elegant and scalable solution.

My suggestion is that you create a service POST /QtdeVendasNoPeriodo/{dtInicio}/{dtFim} . Upon receiving the request, you submit the report generation to a worker thread and immediately respond to the client with HTTP code 202 Accepted and the HTTP header Location with the address where the generation status of the report will be queried. The response to the POST service would be something like:

HTTP/1.1 202 Accepted
Location: https://<seu_endereco_web>/filaProcessamento/sdf4524wrwerwe

sdf4524wrwerwe is any identifier that uniquely reports the generation status of the report. /filaProcessamento/{idStatusProcessamento} is a service GET where you would respond, for example:

http GET https://<seu_endereco_web>/filaProcessamento/sdf4524wrwerwe
HTTP/1.1 200 Ok

<resposta>
    <status>PENDENTE</status>
    <tempoRestante>120 segundos</tempoRestante>
    <link rel="cancel" method="delete" href="/filaProcessamento/sdf4524wrwerwe" />
</resposta>

I used XML above, but it could be JSON. The link tag would be to inform the user of the possibility of canceling the generation of the report. In this case, a DELETE service would be required.

Once the report has been created, the response to the GET service described above would be

http GET https://<seu_endereco_web>/filaProcessamento/sdf4524wrwerwe
HTTP/1.1 303 See Other
Location: https://<seu_endereco_web>/QtdeVendasNoPeriodo/97525252665

The HTTP code 303 is for client redirection. The Location header tells the client where the resource is available. It is necessary that you implement a GET /QtdeVendasNoPeriodo/{idResultado} service, where idResultado is any identifier of the report expected by the client, which will also be controlled by your application.

Some implementation details need to be decided as needed. For example, in response to the GET /QtdeVendasNoPeriodo/{idResultado} service, report in the Expires header how long the report can be cached. Report consistent HTTP codes, such as 404 Not Found , if the report does not exist or 410 Gone after the client has already downloaded the report or your application has discarded the data after a certain period of time. Anyway, several improvements can be thought of.

Security tip: idResultado can be, for example, a large random number or a hash. Thus, any client is likely to be able to access the results of other clients by querying the GET /QtdeVendasNoPeriodo/{idResultado} service. If you use a sequential, for example, a client may have access to other results only by incrementing values of idResultado .

    
23.06.2017 / 19:25