✔ 엔티티가 변동할시 api스펙이 변하기 때문에 엔티티를 보낼시 장애가 날 확률이 높다. 따라서 DTO에 필요한 정보를 담고 api사용자에게 DTO를 보낸다.
✔ 엔티티를 보낼시 확장성이 떨어진다. 사용자의 정보+count를 보내고 싶을 때 엔티티로 보낸다면 각각의 객체마다 count속성이 붙어서 나가는 것이 아닌 count만 담긴 객체가 따로 담겨 나갈 수 밖에 없다. 따라서 api사용자가 원하는 DTO를 설계하고 DTO에 엔티티의 데이터와 보내고 싶은 정보를 담아 보내는 것이 좋다.
//엔티티로 보낼 시, 각 객체에 count라는 필드를 담을 수가 없다.
[
{
"count":1
},
{
"id": 1,
"name": "member1",
"address": {
"city": "서울",
"zipcode": "1111",
"street": "test"
}
}
]
//DTO로 보낼 시, 각 객체에 count라는 필드를 담을 수가 있다.
[
{
"id": 1,
"name": "member1",
"address": {
"city": "서울",
"zipcode": "1111",
"street": "test"
},
"count":1
}
]
✔ DTO로 보낼시 List로 보내지말고 감싸서 통으로 보내라, List로 보내면 json 배열로 보내지기 때문에 유연성이 확 떨어지기 떄문이다.
//List를 data로 감싸서 보낼때
{
"data": [
{
"name": "member1"
},
{
"name": "meber2"
}
]
}
//구현코드
@GetMapping("/api/v2/members")
public Result memberV2() {
List<Member> findMembers = memberService.findMembers();
List<MemberDto> collect = findMembers.stream()
.map(m -> new MemberDto(m.getName()))
.collect(Collectors.toList());
return new Result(collect);
}
@Data
@AllArgsConstructor
static class Result<T>{
private T data;
}
//그냥 List로 보낼때
[
{
"name": "member1"
},
{
"name": "meber2"
}
]
//구현코드
@GetMapping("/api/v2/members")
public List<MemberDto> memberV2() {
List<Member> findMembers = memberService.findMembers();
List<MemberDto> collect = findMembers.stream()
.map(m -> new MemberDto(m.getName()))
.collect(Collectors.toList());
return collect;
}
✔ 필요한 부분만 노출해라, 엔티티 그대로 노출시 외부때문에 내부코드를 바꿀 수 없을 수 있다.