The simple code below is a demo of quarkus rest api with reactive method:
@Consumes
@Produces(MediaType.APPLICATION_JSON)
@Path("/api/v1/datasource")
public class DatasourceResource {
@Inject
DatabaseBoundary databaseBoundary;
@POST
@Path("/query")
public Uni<Response> query(DatasourceQuery param) {
DatasourceRecordDTO result = new DatasourceRecordDTO();
result.setId("888");
List<String> header = Arrays.asList("id", "name", "age");
DatasourceRecordItem item = new DatasourceRecordItem();
item.setKey("888");
item.setValueList(Arrays.asList("123", "wkx", "26"));
result.setHeader(header);
result.setRows(List.of(item));
result.setContent("ok");
return Uni.createFrom().item(Response.ok(result).build());
}
}
I tried to run it with two way:
With The First way, I can have a correct response with content '{xx:xx,xx:xx}':
However, With The Seconde, I can only have an empty response '{}':
Why the response behaved differently in these two running mode?
I tried to replace the Return Type 'Uni<Response>' with normal type, they behaved samely. So I wonder how the native feature made the Uni response disappear?
It's different because the serialization of DatasourceRecordDTO
requires using reflection, which GraalVM does not enable by default.
So in your case if you annotate DatasourceRecordDTO
with @RegisterForReflection
, then everything should work as expected.
Furthermore, if you use are using RESTEasy Reactive, you can use RestResponse<DatasourceRecordDTO>
instead of Response
, which will instruct Quarkus to automatically register DatasourceRecordDTO
for reflection.
Just to elaborate a little more on Uni<Response>
: Quarkus inspects the return type of a JAX-RS method (among other things) to determine which types to register for reflection. Since Response
does not contain a generic type, Quarkus has no way of knowing what type of response was added and therefore cannot automatically register that type for reflection. RestResponse
on the other does have a generic type, so Quarkus can determine what to do in that case.