Parallel calls in Quarkus
A. First solution
Uni<Tuple> parallelCalls(List params) {
return Uni.combine()
.all()
.unis(
restCallA(params),
restCallB(params),
restCallC(params),
)
.asTuple();
}
Uni<ResultA> restCallA(List params) {
return Multi.createFrom().iterable(params)
.invoke(param-> clientA.send(param))
//combine results & return as uni
}
Uni<ResultB> restCallB(List params) {
return Multi.createFrom().iterable(params)
.invoke(param-> clientB.send(param))
//combine results & return as uni
}
Uni<ResultC> restCallC(List params) {
return Multi.createFrom().iterable(params)
.invoke(param-> clientC.send(param))
//combine results & return as uni
}
Useful links:
- Invoking REST APIs asynchronously with Quarkus | Niklas Heidloff
- Concurrent asynchronous actions with Mutiny - Quarkus
- java - Quarkus Mutiny Uni/Multi wait for the request response to finish - Stack Overflow
B. Second solution
To call multiple endpoints in parallel in a Quarkus application, leveraging the reactive nature of Quarkus and the Mutiny library is recommended. This approach allows you to perform asynchronous operations, such as calling multiple REST services concurrently, without blocking the caller thread. Here's a step-by-step guide on how to achieve this:
Use Mutiny for Asynchronous Calls: Mutiny provides a way to work with asynchronous streams and futures in a reactive manner. You can use Uni, Multi, or CompletionStage depending on your needs. For calling multiple endpoints in parallel, Multi is suitable as it represents a stream of items.
Create a Method to Call Endpoints: Define a method that performs the HTTP call to the endpoint. This method should return a Uni or Multi depending on whether you expect a single response or multiple responses.
Call Multiple Endpoints in Parallel: To call multiple endpoints in parallel, create instances of the method defined in step 2 for each endpoint you wish to call. Then, combine these instances into a Multi using Multi.createFrom().iterable() or similar methods.
Process Responses: Once all the calls are completed, you can process the responses. With Mutiny, you can chain operations after the Multi to transform, filter, or aggregate the responses.
Here's an example that demonstrates how to call multiple endpoints in parallel and process the responses:
import io.smallrye.mutiny.Multi; import javax.ws.rs.GET; import javax.ws.rs.Path; import org.jboss.resteasy.client.jaxrs.ResteasyClient; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; @Path("/parallel-calls") public class ParallelCallsResource { private static final ResteasyClient client = new ResteasyClientBuilder() .connectionPoolSize(5) // Adjust based on your requirements .build(); @GET @Path("/multiple-endpoints") public Multi<String> callMultipleEndpoints() { // URLs of the endpoints to call String[] urls = {"http://example.com/api/data1", "http://example.com/api/data2"}; // Create a Multi that emits the URL of each endpoint Multi<String> urlsMulti = Multi.createFrom().items(urls); // Transform each URL into a Uni representing the HTTP call Multi<Uni<String>> callsMulti = urlsMulti.onItem().transform(url -> callEndpoint(url)); // Combine all Unis into a single Multi return callsMulti.merge().onItem().transform(response -> "Response: " + response); } private Uni<String> callEndpoint(String url) { // Perform the HTTP call and return a Uni<String> // This is a simplified example; adjust according to your actual implementation return Uni.createFrom().item(() -> { try { Thread.sleep(1000); // Simulate network latency return "Success: " + url; } catch (InterruptedException e) { throw new RuntimeException(e); } }); } }
This example demonstrates how to set up a Quarkus resource that calls multiple endpoints in parallel and processes the responses. Remember to adjust the callEndpoint method to actually perform the HTTP call using a client like ResteasyClient.
Niciun comentariu:
Trimiteți un comentariu