It is a common pattern in Rest services to have an expand query
parameter with which the client can control which parts of a probably
big response should be returned.
Atlassian for example uses it for the jira rest api: https://docs.atlassian.com/jira/REST/cloud/ section “Expansion”.
At the company I work for we searched for a solution for this problem for java rest services using https://github.com/FasterXML/jackson.
At the server side we are using spring-mvc.
Our first try was to use https://github.com/monitorjbl/json-view. But we found out that this solution did not work together well with special serializers. E.g. we had a serializer for Date values which was defined on one of our DTOs with @JsonSerialize
. This serializer worked well without json-view but was completely ignored when using it. Instead the serialization produced timestamp values.
After having a look at the json-view code we did not see a workaround or simple solution to solve this.
So we started with another solution.
Some ideas have been taken from the json-view. So, the general mechanism is the following:
- in a controller method a thread-local variable is set containing the information which fields from the response should be included and excluded. This can be set using a fluent api in a class called
JsonProfile
(coming later). - we are using an adjusted
ObjectMapper
having aJsonProfileFilter
which extendsSimpleBeanPropertyFilter
. - the
JsonProfileFilter
gets the thread-local json profile and decides which fields to serialize - an interceptor resets the thread-local json profile after request completion
- to make the
JsonProfileFilter
work the DTOs have to be annotated with@JsonFilter("jsonProfile")
Now for some detail code:
The usage of the JsonProfile
in a controller looks like this:
JsonProfile.get()
.exclude(ClassA.class, "*")
.include(ClassA.class, "id")
.include(ClassA.class, expandedProperties);
where expandedProperties
is set from a request parameter expand
.
This says: exclude every field from ClassA except id
and the properties to be expanded. If the parameter expand
is not set, only the id
will be contained in the response.
The complete JsonProfile class is
The jackson framework is initialized with some adjustments.
In a configuration extending WebMvcConfigurationSupport
:
where objectMapperWithFilter
is
And the JsonProfileFilter
is
The whole solution is not as easy to use than json-view but it works for us. Now, once we made the preparations we just have to put the @JsonProfile
annotation on DTOs where we want to expand and use the JsonProfile
in the controller methods.