When implementing a reactive endpoint, is there any difference between returning Uni<List<T>>
vs Multi<T>
?
@Path("/fruits")
public class FruitResource {
@GET
@Path("uni")
public Uni<List<Fruit>> getUni() {
return Fruit.listAll();
}
@GET
@Path("multi")
public Multi<Fruit> getMulti() {
return Fruit.streamAll();
}
}
I find it easier to use a Multi
because I can simply transform each each element to a DTO using onItem().transform(fruit -> ...)
With an Uni
, I would get a List
in the transform
method which is less convenient.
In all Quarkus guides, I see they are using a Uni<List>>
, is there any good reason for using this rather than a Multi
?
In this particular use case, there isn't much difference in using one or the other. Except that the default response header from the rest API will change (it's subtle, but some clients might behave differently based on what you are doing):
For Uni:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
content-length: 75
For Multi:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
transfer-encoding: chunked
This is because a Multi
is supposed to be used when one generates a stream of potentially endless events (like geod said in the other answer).
If you are using Panache with Hibernate Reactive, streaming the results from a query on the database is not supported. So, the current implementation of Fruit.streamAll
just converts the Uni<List<Fruit>>
into a Multi<Fruit>
.
You can see the code on GitHub:
Uni<List<T>> results = list();
return (Multi<T>) results.toMulti().flatMap(list -> {
return Multi.createFrom().iterable(list);
});