javamicronautmicronaut-clientmicronaut-rest

Multiple query values binding in POJO


I have a simple controller and rest API as below in which I want to map 'name', 'price' and 'description' querie values into ProductSearchCriteria :

    @Controller("/api/v1/product")
    public class ProductController {
        private static final Logger LOG = LoggerFactory.getLogger(ProductController.class);
    
        @Operation(summary = "Find all products")
        @ApiResponses(value = {@ApiResponse(content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ProductViewModel.class))})})
        @Get(uri="/")
        List<ProductViewModel> find(@Valid ProductSearchCriteria searchCriteria) {
            LOG.info("Finding all the products");
            //return productProducer.find(searchCriteria);
            return new ArrayList<>();
        }
    }

product search criteria

public class ProductSearchCriteria {
    @JsonProperty("name")
    Optional<String> name;

    @JsonProperty("price")
    Optional<Float> price;

    @JsonProperty("description")
    Optional<String> description;

    public Optional<String> getName() {
        return name;
    }

    public void setName(Optional<String> name) {
        this.name = name;
    }

    public Optional<Float> getPrice() {
        return price;
    }

    public void setPrice(Optional<Float> price) {
        this.price = price;
    }

    public Optional<String> getDescription() {
        return description;
    }

    public void setDescription(Optional<String> description) {
        this.description = description;
    }
}

Error

Error: 400 Bad Request
    {
      "message": "Required argument [ProductSearchCriteria searchCriteria] not specified",
      "path": "/searchCriteria",
      "_links": {
        "self": {
          "href": "/api/v1/product?name=string&price=0&description=string",
          "templated": false
        }
      }
    }

Solution

  • You missed something on the @Get annotation

        @Operation(summary = "Find all products")
        @ApiResponses(value = {@ApiResponse(content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ProductViewModel.class))})})
        @Get(uri="/{?searchCriteria*}")
        List<ProductViewModel> find(@Valid ProductSearchCriteria searchCriteria) {
            LOG.info("Finding all the products");
            //return productProducer.find(searchCriteria);
            return new ArrayList<>();
        }
    

    You also miss an @Introspected on your ProductSearchCriteria POJO.

    Since you are using @ValidI would go with validation annotation inside ProductSearchCriteria in place of Optional