javaquarkusquarkus-rest-client

How to pass GET query parameters in Quarkus as POJO object?


I'm switching from Spring to Quarkus and this doesn't seem to work the same way.

There are classes defined:

@Path("/example")
public class ExampleResource {

  @GET
  public List<String> search(ExampleSearchParams params) {
    Log.info(params);
    return List.of();
  }

}
public record ExampleSearchParams(
  String searchQuery,
  Integer size,
  Integer from
) {
}

Now after querying URL /example?size=10 or /example?size=10&from=10&searchQuery=test you get HTTP ERROR 415.

Try 1. According to docs, you need to annotate with @BeanParam

@Path("/example")
public class ExampleResource {

  @GET                    // v HERE
  public List<String> search(@BeanParam ExampleSearchParams params) {
    Log.info(params);
    return List.of();
  }

}

Now the Quarkus app fails to start:

ERROR [io.qua.dep.dev.IsolatedDevModeMain] (main) Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors

[error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: Found 3 deployment problems: 

[1] Unsatisfied dependency for type java.lang.String and qualifiers [@Default]

[2] Unsatisfied dependency for type java.lang.Integer and qualifiers [@Default]

[3] Unsatisfied dependency for type java.lang.Integer and qualifiers [@Default]

Try 2. Add @RestQuery annotations

public record ExampleSearchParams(
  @RestQuery
  String searchQuery,
  @RestQuery
  Integer size,
  @RestQuery
  Integer from
) {
}

Still the same error on Quarkus app startup.

Try 3. Use @RestQuery directly on object parameter.

@Path("/example")
public class ExampleResource {

  @GET
  public List<String> search(@RestQuery ExampleSearchParams params) {
    Log.info(params);
    return List.of();
  }

}

And the Quarkus app fails to start with error:

Caused by: java.lang.RuntimeException: Could not create converter for ExampleSearchParams for method java.util.List<java.lang.String> search()

In pom.xml there is dependency

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-reactive-jackson</artifactId>
    </dependency>

Any workaround for this?


Solution

  • TLDR; BeanParams are not working with Java Records yet.

    Quarkus 3 supports Jakarta EE APIs. The latest JakartaEE 10 specification contains Restful Web Services 3.1 component which is on Java 11.

    According to this discussion on JakartaEE's GitHub project v4.0 will be supporting Java 17 (or later)

    Using traditional java class will solve this problem

    public class ExampleSearchParameters {
        @QueryParam("query")
        String searchQuery;
        @QueryParam("page_size")
        Integer size;
        @QueryParam("page_index")
        Integer from;
    }
    

    Don't forget to put annotations on fields (e.g. @QueryParam).

    Now, this POJO can be injected as a @BeanParam like this:

    @Path("/example")
    public class ExampleResource {
    
        @GET
        public List<String> hello(@BeanParam ExampleSearchParameters filterParams) {
            return List.of("query:" + filterParams.searchQuery, "size: " + filterParams.size, "from:" + filterParams.from);
        }
    }