We have problems deserializing a query parameter with square bracket notation (?paging[offset]=3) in Jersey.
We're using Jersey JAX-RS and annotating our endpoints and beans with swagger OpenAPI, and have tooling to generate our documentation automatically. We want to follow the JSON:API standard for describing a new API. JSON:API specifies that to implement paging, the API must accept a query parameter in the format : ?paging[offset]=0&paging[limit]=10
Our swagger annotations support this out of the box, allowing us to specify
@Parameter(
description = "paging",
style = ParameterStyle.DEEPOBJECT,
explode = Explode.TRUE)
Which is compatible with the square bracket notation paging[offset] and so on. And it generates the correct documentation for our paging parameter. All is good and great and dandy.
JAX-RS is the problem. There's a @QueryParam annotation in JAX-RS. But, to use a complex object with the @QueryParam annotation, that type must have a constructor with a single String parameter. No problem. Let's add a constructor to our paging bean.
public class PagingBean {
public PagingBean(String stringValue){...}
@XmlElement
public getOffset(){...}
public setOffset(int offset){...}
@XmlElement
public getLimit(){...}
public setLimit(int limit){....}
}
So our endpoint now looks like
@Get("/path")
public Response someEndpoint(
@Parameter(description = "paging",style = ParameterStyle.DEEPOBJECT,explode = Explode.TRUE) @QueryParam("paging") PagingBean paging
){
...
}
But if we hit our api with
GET /rest/path?paging[limit]=10&paging[offset]=5
We can see that the paging request parameter is null. It seems like Jersey didn't even recognize that the paging[... is part of the paging QueryParam. Probably that it expects exactly the paging key, and not a paging\[?-like key.
We can confirm this by injecting a @Context UriInfo ui and checking the request parameters. Their key are paging[offset] and paging[limit]
One solution to this is to flatten our parameters in the endpoint like so
@QueryParam("paging[limit]") pagingLimit,
@QueryParam("paging[offset]") pagingOffset
But this is not very nice to look at.
Ideas on how to deserialize this in Jersey ?