Assuming I have these three DTO's
data class CountryDTO(
val name: String,
val isoAlpha3: String,
val subContinent: SubContinentDto,
val continent: ContinentDto
)
data class SubContinentDTO(
val name: String,
val continent: ContinentDto
)
data class ContinentDTO(
val name: String,
)
A response with a single CountryDTO
in it would have duplicated values: ContinentDTO
would be in CountryDTO
and nested in SubContinentDTO
. If I return a CountryDTO
, I would not want ContinentDTO
to be nested in SubContinentDTO
, but only "on the first level" of CountryDTO
.
But, if I return a SubContinentDTO
, I would want a ContinentDTO
to be in there, becaue now its not nested anymore.
Now, I could create a CountryNotNestedDTO
which would contain a SubContinentNotNestedDTO
data class CountryNotNestedDTO(
val name: String,
val isoAlpha3: String,
val subContinent: SubContinentNotNestedDTO,
val continent: ContinentDto
)
data class SubContinentNotNestedDTO(
val name: String,
)
But this feels rather strange... Is there a way to tell Jackson to exclude certain properties from classes, depending on where the class is used? Or is there something else I could do in order not to have these more or less duplicated DTOs?
This is a typical problem when creating an API. I know of 3 ways of doing this:
Move all the common field into a separate SubCountinentFlatDto
. And in your SubContinentFullDto
include the common SubCountinentFlatDto
and mark it as @JsonUnwrapped
- this way during serialization all the nested fields are going to be included in the parent object.
Use inheritance, but this will limit you in how flexible you want to be in separating the DTOs because multiple inheritance isn't a thing in Java.
Use @JsonView
to mark that this field is applicable only in certain contexts. During (de)serialization you'll need to specify which views you're interested in. However, this is a questionable practice because later you'll be passing this object to your methods which won't know about views and won't know which fields to use or not.
A typical situation when you want to have different sets of fields is POST
ing a resource (the id
field should be excluded) and GET
ing resource (id
must be present).