CS 잡지식
Rest API 개발 시, List<E> 등의 [컬렉션]을 [직접] 반환하지 말 것!
JIN_YOUNG _KIM
2023. 5. 3. 15:50
결론부터 말을 하자면,
컬렉션을 [직접] 반환하면 항후 API 스펙을 변경하기 어렵기 때문에,
컬렉션을 별도의 클래스로 한 번 Wrapping을 한 후에 넘겨줘야 한다(무슨 말인지는 아래를 천천히 읽어 보자).
(사전 지식 : JSON은 실체는 <KEY,T>쌍의 배열이다
EX)
"id": 1,
"name": "jin young kim",
위와 같은 JSON이 있다고 하자.
이것의 실체는 List<[key,value]> json = new ArrayList<>()에 불과하다.
"id": 1,
"name": "jin young kim",
"address": {
"city": "해운대구",
"street": "해운대로781번길23, 101동 1702호",
"zipcode": "48102"
}
위 address는 컬렉션이 반환이 된 것이다.
json[x] == <"address" , 컬렉션 >이 화면에 뿌려진 것이다.
)
근데, address 컬렉션을 [직접] 반환하여 화면에 뿌리는 것에는 어떠한 문제점이 있을까??
-> API 개발 시, [유연성]이 떨어진다는 것이다.
이런 시나리오를 생각해 보자.
"COUNT" : 1
"DATA" : [
{ "id": 1,
"name": "jin young kim",
"address": {
"city": "해운대구",
"street": "해운대로781번길23, 101동 1702호",
"zipcode": "48102" }
]
위와 같은 형태로 Rest API의 호출 결과를 [변경]을 한다고 해보자.
@GetMapping("/api/v1/members")
public List<Member> membersV1(){ //[회원 조회]용 Rest API - 1
return memberService.findMembers(); // [도메인 엔티티]를 반환! ( memberV2()에서 개선할 예정 )
// 그리고 컬렉션(List<Member>)를 [직접] 반환하고 있다.
}
위와 같이 컬렉션을 [직접] 반환을 하는 형태로는 도저히 위와 같이 JSON 형태를 변경할 재간이 없다.
즉, [유연성]이 떨어 진다.
아래에 해결 방안이 있다.
@GetMapping("api/v2/members")
public Result membersV2(){ //[회원 조회]용 Rest API - 2
List<Member> findmembers = memberService.findMembers();
//1] findMembers 컬렉션을 [MemberDTO 컬렉션]으로 변환
List<MemberDTO> memberDTO = findmembers.stream()
.map(m -> new MemberDTO(m.getName()))
.collect(Collectors.toList());
// 2] [MemberDTO 컬렉션]을 Result 클래스의 필드값으로 넘겨서 반환함으로서, 컬렉션을 [직접] 반환하는 것이 아닌,
// Result 객체의 필드값으로[간접적]으로 컬렉션을 넘김.
// 즉, 컬렉션을 한 번 Wrapping을 해서, 넘겨야 한다.
return new Result(1,memberDTO);
}
@Data
@AllArgsConstructor
public static class Result<T>{
private int count;
private T data; // Rest API를 호출한 개발자의 화면에는 "data" : "[회원 목록1,2,3,,,,,n]" 형태로 보여질 것이다.
// https://jbluke.tistory.com/411 사이트를 참조하면 보여지는 화면의 차이점인지 파악 가능할 것이다.
}
@Data
@AllArgsConstructor
public static class MemberDTO{
private String name;
}
컬렉션을 직접 반환하는 것이 아니라, 컬렉션을 별도의 클래스로 한 번 Wrapping을 하여 [간접적]으로 반환을 하였다.
결론 : Collection은 반드시 별도의 클래스를 작성하여 1번 Wrapping해서 전달하자!!!!