O java-restify oferece suporte para requisições assíncronas de maneira bastante simples.
Um detalhe de implementação importante é que o java-restify diferencia a execução assíncrona do método da execução assíncrona da requisição.
Tipos de retorno assíncronos
Conforme comentado na documentação sobre tipos de retorno de método, alguns tipos, como Future, CompletableFuture, irão automaticamente forçar que o método seja executado em uma thread diferente.
Outro tipo que pode ser utilizado como retorno do método é o AsyncEndpointCall, um objeto fornecido pelo java-restify que representa a execução assíncrona de uma requisição.
publicinterfaceMyApi { @Path("/customers/{id}") @GetAsyncEndpointCall<Customer> getCustomerById(@PathParameterString id);}MyApi myApi =newRestifyProxyBuilder().target(MyApi.class).build();AsyncEndpointCall<Customer> call =myApi.getCustomerById("abc123"); // lazy - a requisição ainda não foi realizadacall.executeAsync().thenAccept(customer ->...) //outra thread
Callbacks
Outra abordagem é, ao invés de lidar com o retorno do método, é utilizar argumentos de callback, usando a anotação @CallbackParameter:
Ao utilizar parâmetros anotados com @CallbackParameter, o retorno do método deve ser void.
importcom.github.ljtfreitas.restify.http.contract.CallbackParameter;importcom.github.ljtfreitas.restify.http.client.call.async.EndpointCallSuccessCallback;importcom.github.ljtfreitas.restify.http.client.call.async.EndpointCallFailureCallback;importcom.github.ljtfreitas.restify.http.client.call.async.EndpointCallCallback;publicinterfaceMyApi {/* callback do tipo java.uil.function.BiConsumer: uma função que recebe o objeto de resposta e a exceção (se houver) */ @Path("/customers/{id}") @GetvoidgetCustomerById(@PathParameterString id, @CallbackParameterBiConsumer<Customer,Throwable> callback);/* EndpointCallSuccessCallback permite capturar a resposta deserializada como um objeto. Essa interface possui um único método onSuccess(T response) */ @Path("/customers/{id}") @GetvoidgetCustomerById(@PathParameterString id, @CallbackParameterEndpointCallSuccessCallback<Customer> success);/* EndpointCallFailureCallback permite capturar a exceção gerada pela requisição HTTP, se houver. Essa exceção pode ser um problema de I/O ou uma resposta de erro (4xx, 5xx) Essa interface possui um único método onFailure(Throwable throwable): */ @Path("/customers/{id}") @GetvoidgetCustomerById(@PathParameterString id, @CallbackParameterEndpointCallFailureCallback failure);/* É possível usar parâmetros dos dois tipos */ @Path("/customers/{id}") @GetvoidgetCustomerById(@PathParameterString id, @CallbackParameterEndpointCallSuccessCallback<Customer> success, @CallbackParameterEndpointCallFailureCallback failure);/* Existe uma terceira interface chamada EndpointCallCallback, que extende EndpointCallSuccessCallback e EndpointCallFailureCallback. Essa interface também é uma opção caso você precise dos dois callbacks (sucesso e falha) */ @Path("/customers/{id}") @GetvoidgetCustomerById(@PathParameterString id, @CallbackParameterEndpointCallCallback<Customer> callback);}
Configuração
Os handlers responsáveis pela execução de métodos assíncronos utilizam o mesmo thread pool configurado para requisições assíncronas. Por padrão, é utilizad um Executor criado a partir do método Executors.newCachedThreadPool).
Se a configuração padrão não atender as necessidades da sua aplicação, o Executor pode ser facilmente customizado:
Os exemplos acima demonstram o suporte do java-restify para execução assíncrona de métodos, usando o tipo de retorno ou argumentos de callback. Nesse cenário, o java-restify irá apenas executar em outra thread os mesmos passos de qualquer chamada de método. O ponto a ser observado aqui é que a requisição HTTP continua a ser uma operação bloqueante, mas sendo realizada em uma thread separada.
Isso é útil, mas eventualmente pode ser importante utilizarmos os recursos assíncronos do próprio client HTTP, como por exemplo I/O não-bloqueante ou algum suporte especializado fornecido pela própria biblioteca. O java-restify também oferece uma API específica para clientes HTTP assíncronos. Os detalhes são explicados mais profundamente na documentação sobre clientes HTTP.
Se o java-restify estiver configurado para utilizar um cliente HTTP assíncrono, então os recursos específicos da implementação serão utilizados; se não for o caso (como é o padrão), a execução do método (incluindo a requisição HTTP) apenas será feita em uma thread separada (conforme detalhado acima).