Reputation: 1
I'm still new to Reactive programming and trying to learn how to use mutiny's Unis and Multis properly in web services.
Let's say that I have a RestClient that I can use to access multiple endpoints, each one of them returning a different data type:
@ApplicationScoped
@RegisterRestClient(config-key = "some-external-service")
public interface MyRestClient {
@GET
@Path("/endpoint-1")
public Uni<String> getStringData();
@GET
@Path("/endpoint-2")
public Uni<CustomResponseType> getCustomData();
@GET
@Path("/endpoint-3")
public Uni<AnotherResponseType> getAnotherData();
}
And I need to combine some data from each request to build my own response:
public class MyResponseType {
private String someString;
private Integer someInteger;
private Integer someOtherInteger;
// getters and setters...
}
I can do it synchronously, like this:
@Path("my-endpoint")
public class MyService {
@Inject
@RestClient
MyRestClient myRestClient;
private MyResponseType myResponse;
// Timeout for each request
private static final Duration TIMEOUT = Duration.ofSeconds(2);
@GET
public MyResponseType getData() {
myResponse = new MyResponseType();
// Suppose that I might do some complex manipulation on the data
// returned by the client, so I'd like to keep it in
// separate methods
fetchStringData();
fetchIntegerData();
fetchOtherIntegerData();
return myResponse;
}
private void fetchStringData() {
String stringData = myRestClient.getStringData().await().atMost(TIMEOUT);
myResponse.setSomeString(stringData);
}
private void fetchIntegerData() {
Integer integerData = myRestClient.getCustomData()
.await().atMost(TIMEOUT)
.getInteger();
myResponse.setSomeInteger(integerData);
}
private void fetchOtherIntegerData() {
Integer otherIntegerData = myRestClient.getSomeOtherData()
.await().atMost(TIMEOUT)
.getInteger();
myResponse.setSomeOtherInteger(otherIntegerData);
}
}
However this doesn't scale well, of course, because the application waits for each response before making the next request, even though they are independent of each other.
I think I could make it so that each method returns a Uni rather than being void, and then use Uni.join() to wait for them to complete before returning the response. However, I don't know how I would do it in this case, because each of the responses is of a different data type.
I did not find many examples on the Mutiny documentation about combining heterogeneous data types, which is a must when you need to consume from multiple http servers or databases.
Upvotes: 0
Views: 380
Reputation: 64059
You can use Uni.combine() like so:
Uni<Tuple3<String, CustomResponseType, AnotherResponseType>> tuple3 = Uni.combine().all()
.unis(getStringData(), getCustomData(), getAnotherData()).asTuple();
Uni<MyResponseType> = tuple3.map(t3 -> new MyResponseType(...))
Upvotes: 1