Quarkus Reactive: post-process the value returned by the Uni?

31 views Asked by At

I have a json array encoded as a string:

String jsonString = """
    [
      { "key1": "value11", "key2": "value12" },
      { "key1": "value21", "key2": "value22" }
    ]
""";

I wanted to parse that jsonString with Jackson, and return it:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;

return objectMapper.readValue(jsonString, typeFactory.constructCollectionType(List.class, Object.class));

It works well in debugger and jshell. However when I try to return it from reactive framework (quarkus, mutiny) I still get the original jsonString.

@GET
@Path("{category}/items")
@WithSession
public Uni<List<Object>> listItemsOfCategory(@PathParam("category") String category) {

  // this is the list of a single string:
  final string postgresQueryTemplate = """
    with
      data as (
      -- ...
      )
    select
      cast(json_agg(row_to_json(data.*)) as text)
    from data
  """;

  ObjectMapper objectMapper = new ObjectMapper();
  TypeFactory typeFactory = objectMapper.getTypeFactory();

  return Panache.getSession()
    .onItem()
    .transformToUni(session -> session.createNativeQuery(postgresQueryTemplate).setParameter(1, category)
       .getSingleResult()
       .invoke(jsonString -> {
           try {
               objectMapper.readValue(jsonString, typeFactory.constructCollectionType(List.class, Object.class));
           } catch (JsonProcessingException e) {
               throw new RuntimeException(e);
           };
         }
       )
    );
}

How do I replace the value returned by the getSingleResult() in invoke?

1

There are 1 answers

0
Adobe On

After reading mutiny documentation, I got it working with:

@GET
@Path("{category}/items")
@WithSession
public Uni<Object> listItemsOfCategory(@PathParam("category") String category) {

  // this is the list of a single string:
  final string postgresQueryTemplate = """
    with
      data as (
      -- ...
      )
    select
      cast(json_agg(row_to_json(data.*)) as text)
    from data
  """;

  return Panache.getSession()
    .onItem()
    .transformToUni(session -> session.createNativeQuery(postgresQueryTemplate)
         .setParameter(1, category)
         .getSingleResult()
       )
    .onItem().transform(queryResult -> {
          String jsonString = queryResult.toString();

          ObjectMapper objectMapper = new ObjectMapper();
          TypeFactory typeFactory = objectMapper.getTypeFactory();

          Object json = null;
          try {
              json = objectMapper.readValue(jsonString, typeFactory.constructCollectionType(List.class, Object.class));
          } catch (JsonProcessingException e) {
              throw new RuntimeException(e);
          }
          return json;
        }
     );
}