Issue
We are currently designing response dto for user information. However, while designing, there are too many overlapping parts for fields, which is a concern.
Assume that user data includes id, email, name, phone number, and manager id in charge (actually, more diverse data is included). When a general user can search for a user, the phone number and contact ID should not be shown in the user data. Even if the person inquires user own data, user cannot inquire his/her person in charge ID. The administrator can inquire all the above data. We even plan to categorize the response DTO to show in the list and the DTO for detailed inquiry.
The data based on the example above is as follows:
@Getter
@Builder
@AllArgsConstructor
public class MemberResponseDTOForNormalUser {
private final Long id;
private final String name;
private final String email;
private final Integer grade;
private final Integer generation;
private final String major;
private final String blogUrl;
private final String githubId;
private final String profilePhotoUrl;
private final List<String> tags;
private final String introduction;
}
@Getter
@Builder
@AllArgsConstructor
public class MemberResponseDTOForMyself {
private final Long id;
private final String name;
private final String email;
private final Integer grade;
private final Integer generation;
private final String major;
private final String studentId;
private final String blogUrl;
private final String githubId;
private final String phoneNumber;
private final String profilePhotoUrl;
private final List<String> tags;
private final String introduction;
}
@Getter
@Builder
@AllArgsConstructor
public class MemberResponseDTOForAdmin {
private final Long id;
private final String name;
private final String email;
private final Integer grade;
private final Integer generation;
private final String major;
private final String studentId;
private final String blogUrl;
private final String githubId;
private final String profilePhotoUrl;
private final List<String> tags;
private final String introduction;
private final Member adminId;
}
When designing as above, there are too many overlapping parts in the field. I want to use abstraction to reduce redundancy, but I'm not sure if this is a good way to do it.
public abstract class MemberResponseDTO {
private final Long id;
private final String name;
private final String email;
private final Integer grade;
private final Integer generation;
private final String major;
private final String blogUrl;
private final String githubId;
private final String profilePhotoUrl;
private final List<String> tags;
private final String introduction;
}
How should I address these issues? If you have any good comments, please feel free to comment!
ps: Naming method for dto is also recommended!
Solution
solution1.
i think you could compose all the propety into single model, and then annotation the specifial property into JsonViews. such as:
@JsonView(View.User.class)
private int id;
@JsonView(View.User.class)
private String name;
@JsonView(View.Admin.class)
private String ownerName;
and then assign view via role
There is pretty good tutorial ,https://www.baeldung.com/jackson-json-view-annotation
solution2
i think maybe you could use filter to process exclude/include fiels depend your actual need in controller. for example:
@JsonFilter("fieldFilter")
public class MemberResponseComposeDto{
// there compose all your fields
}
public class MemberResponseComposeDtoTestController{
public MappingJacksonValue query() {
List<MemberResponseComposeDto> res= ...;
MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(res);
SimpleBeanPropertyFilter.serializeAllExcept("field1","field2","field3");
//or
SimpleBeanPropertyFilter.filterOutAllExcept("field1","field2","field3");
FilterProvider filterProvider = new SimpleFilterProvider().addFilter("fieldFilter", f);
mappingJacksonValue.setFilters(filterProvider);
return mappingJacksonValue;
}
}
Answered By - smileis2333
Answer Checked By - Terry (JavaFixing Volunteer)