익숙하게 사용했던 패턴이지만 표준인 줄 모르고 넘어갔던 내용을 스프링의 API 작성을 공부하던 중에 다시 보게되어 확실히 정리하기위해 포스팅함
Django의 Serailizer에 many=True 옵션을 주는 경우
+
Spring에서 @RestController를 사용해 Entity를 그대로 반환하는 경우
API의 response를 보면 아래와 같이 []배열 형태로 Json이 반환된다.
[
{
"id": 1,
"name": "newhello",
"address": null,
"orders": []
},
{
"id": 2,
"name": "member1",
"address": {
"city": "서울",
"street": "test",
"zipcode": "1234"
},
"orders": []
},
{
"id": 3,
"name": "member2",
"address": {
"city": "busan",
"street": "kdkdk",
"zipcode": "1515"
},
"orders": []
}
]
이 경우에 count 정보를 주고 싶어서 "count"를 추가하면 Json 형식이 깨져버리는걸 볼 수 있다.
[
"count": 3,
{
"id": 1,
"name": "newhello",
"address": null,
"orders": []
},
{
"id": 2,
"name": "member1",
"address": {
"city": "서울",
"street": "test",
"zipcode": "1234"
},
"orders": []
},
{
"id": 3,
"name": "member2",
"address": {
"city": "busan",
"street": "kdkdk",
"zipcode": "1515"
},
"orders": []
}
]
올바른 형식으로 수정
{
"count": 3,
"data": [
{
"id": 1,
"name": "newhello",
"address": null,
"orders": []
},
{
"id": 2,
"name": "member1",
"address": {
"city": "서울",
"street": "test",
"zipcode": "1234"
},
"orders": []
},
{
"id": 3,
"name": "member2",
"address": {
"city": "busan",
"street": "kdkdk",
"zipcode": "1515"
},
"orders": []
}
]
}
data : []
"data"를 추가해서 Json 형식의 일관성을 높이자.
유지보수도 높아지고, 얼마든지 Response에 추가적인 정보를 넣기가 편리할 것이다.
Spring에서는 각 API의 Response에 대한 DTO를 만들어서 상황에 맞게 잘 수정해서 사용하면 된다.
@GetMapping("/api/v2/members")
public Result membersV2() {
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;
}
@Data
@AllArgsConstructor
static class memberDto {
private String name;
}
Django에서는 Serailizer를 거친 serializer.data를 새롭게 딕셔너리로 매핑해서 사용하면 될 것이다.
context = {"data": serializer.data}