I am new to reactive programming with vertx & muntiny (quarkus). I have the below requirement:
Structure: External API call returns -> Response
class Response {String abc; List<AnotherClass> another; ...}
class AnotherClass { List<Role>> roles ...}
DB call returns Uni<List<RoleFromDB>> rolesDB
I want the below call to be done in a reactive way in a chain. Can someone please guide me how to correctly do this.
- Call external API. 2. Call DB (postgres with reactive Hibernate & Panache) with some id value received from the API. 3. Add the DB query result to the result from API and return as a new
Uni<Response>
Also can you please show me an example of calling the external API in a reactive way? I am not able to find any proper material for this online.
This is what I am currently doing.
Uni<List<RolesfromDB>> roles == db call returning Uni<List<RoleFromDB>>
roles.chain(role -> {
Response res = Unirest.get(url).header(...);
//Is calling external endpoint this way fine?
Uni<Response> uniRes = Uni.createFrom().item(res);
//do some operation with uniRes to assign role to the response object and return a new Uni<Response> ...
});
Is this correct or I need to use other means like
io.vertx.axle.ext.web.client.WebClient?
An example on right way to call external API will be very much appreciated.
I would recommend two approaches.
When using the reactive REST client (see https://quarkus.io/guides/rest-client-reactive), you create a Java interface that abstracts the HTTP interactions. A proxy is generated for you, so you don't need a low-level HTTP client. This reactive client supports both blocking and non-blocking. So, in your case, you will have something like:
@GET
Uni<Response> invokeMyService(Role role)
And then, in your pipeline, you do:
roles.chain(role -> client.invokeMyService(role));
This is more low-level, and it should only be used if the reactive rest client cannot handle your specific case. In this case, you will do something like this:
public MyClass(Vertx vertx) { // io.vertx.mutiny.core.Vertx
this.client = WebClient.create(vertx); // io.vertx.mutiny.ext.web.client.WebClient
}
// ...
roles.chain(role -> {
var req = this.client.getAbs(url); // using GET, use the method you need
// Add headers and so on
return req.send()
.map(resp -> resp.bodyAsJsonObject().mapTo(Response.class);
});