I am writing actuator endpoint having two @ReadOperation
-s, one without @Selector
, one with:
@ReadOperation
without the selector is returning a collection of DTOs. That DTO contains a potentially long List of objects. To avoid cluttering output with all elements of the list, I would like to return only last element of the list in each DTO.@ReadOperation
with the selector is returning one DTO. In that case, I want to return all elements of the inner DTO list.
A convenient way to do this is by using Jackson's Serialization Views. Two views are defined, and @JsonView
annotations are added to DTO getters and methods annotated with @ReadOperation
. The output is not affected by annotations presence.
Simplified example:
public interface DtoView {
public interface Last {
}
public interface All {
}
}
public class Dto {
private List<Element> elements;
...
@JsonView(DtoView.Last.class)
public Element getLastElement() {
...
}
@JsonView(DtoView.All.class)
public List<Element> getElements() {
...
}
}
@Endpoint(id = "example")
public class ExampleEndpoint {
@ReadOperation
@JsonView(DtoView.Last.class)
public Collection<Dto> read() {
...
}
@ReadOperation
@JsonView(DtoView.All.class)
public Dto read(@Selector String selector) {
...
}
}
After converting actuator endpoint to @RestContoler output is affected.
Simplified example:
@RestController
public class ExampleControler {
@GetMapping(path = "/example", produces = MediaType.APPLICATION_JSON_VALUE)
@JsonView(DtoView.Last.class)
public Collection<Dto> read() {
...
}
@GetMapping(path = "/example/{selector}", produces = MediaType.APPLICATION_JSON_VALUE)
@JsonView(DtoView.All.class)
public Dto read(@PathVariable String selector) {
...
}
}
Having in mind that Jackson's Serialization Views are supported in Spring Framework since version 4.2, it will be nice to have similar support for actuator endpoints.
Comment From: philwebb
I'm personally not too keen to tie our actuator infrastructure any further Jackson. We have a long standing issue to support other serialization technologies and I think adding direct @JsonView
support would make that harder.
If you're happy only supporting Spring MVC, you could look at the @ControllerEndpoint
annotation which should allow you to use more MVC features.
Comment From: philwebb
Flagging to see what the rest of the team think about adding @JsonView
support.
Comment From: bclozel
See #20291 for the actuator-specific JSON mapper instance.
Also, we probably want to deprecate/transform the existing @ControllerEndpoint
if we want to achieve #20290.
Comment From: wilkinsona
I'm personally not too keen to tie our actuator infrastructure any further Jackson
That's my feeling too. An alternative to @ControllerEndpoint
that also allows you to continue to use the Actuator endpoint infrastructure, you could use an ObjectMapper
in your operation methods to turn the DTO into a Map
and apply any views at that time.
Comment From: zeljko-mirovic
@wilkinsona, thank you for the idea to turn the DTO into a Map and return Map instead.
Comment From: philwebb
Since there's a work-around, I'm going to politely decline this one. Thanks anyway for the suggestion.