🗯️ 문제 : RESTful API 의 응답 데이터를 어떻게 잘 담을까?
RESTful API을 준수하기 위해선 다음 항목들을 알고 실천해야 합니다.
- Uniform (유니폼 인터페이스)
- Stateless (무상태성)
- Cacheable (캐시 가능)
- Self-descriptiveness (자체 표현 구조)
- Client - Server 구조
- 계층형 구조
위 항목 중 이번 시간에 다뤄볼 내용은 Self-descriptiveness (자체 표현 구조) 인데요,
클라이언트 - 서버 사이에서 오고가는 요청 메세지를 보고 해당 메세지가
- 어떤 행위를 하고
- 어떤 리소스를 요구하고(반환하고)
- 해당 요청에 대한 응답이 어떤 결과를 가졌는지
를 바로 알 수 있어야 위 항목을 준수한다고 볼 수 있습니다.
1️⃣ 어떤 행위를 하고?
먼저 첫번째 사항에 대해선 HTTP Method를 적절히 사용해야 합니다. 예를 들어 4가지 Method를 통해 CRUD에 해당하는 행위를 표현할 수 있는데요.
- Post : 리소스 생성
- Get : 리소스 조회
- Put : 리소스 수정
- Delete : 리소스 삭제
클라이언트와 서버 간의 위 행위에 대한 정의가 API 에 잘 담겨있을수록 더욱 Self-descrptiveness 에 다가갈 수 있습니다.
2️⃣ 어떤 리소스를 요구하고(반환하고)
두번째 사항을 준수하기 위해선 위에서 정의한 HTTP Method에 맞는 Best Practice를 찾아볼 필요가 있습니다. HTTP Method(행위)에 따라
- URI 는 어떤 형식으로 이루어져야 하는지
- path variable 로 어떤 데이터를 주고 받을까
- query parameter 로 어떤 데이터를 주고 받을까
- HTTP Body에 데이터를 담을 것인지, 어떻게 담을 것인지
에 대한 내용을 알아보고 이를 준수했을 때, 좀 더 통일된 HTTP API를 작성할 수 있습니다.
3️⃣ 해당 요청에 대한 응답이 어떤 결과를 가졌는지
세번째 사항은 HTTP 상태 코드에 관한 내용입니다. 요청에 대한 결과가 어떻게 됐는지 클라이언트가 아는 것도 매우 중요합니다. 이를 표현해줄 수 있는 방법은 HTTP Status Code를 HTTP STATUS CODE 문서 를 보고 맞는 결과의 종류에 맞게 설정할 수 있습니다.
백엔드 서버를 개발하는 프로젝트를 진행하면서, RESTful API 답게 응답 데이터(json(DTO), 상태코드)를 편리하게 생성하여 전송할 수 있는 방법이 궁금해졌습니다. ( >> 밑에서 공개 )
🔥 해결 방법 : ResponseEntity로 쉽게 응답해보자!
어떻게 하면 상태코드도 담고 DTO도 담고 간결하게 클라이언트로 응답 데이터를 보낼 수 있을까요?
spring에선 위 기능을 ResponseEntity.class를 통해 제공합니다.
먼저 ResponseEntity는 HttpEntity를 상속하는 클래스입니다. 따로 1️⃣ status라는 필드를 가지며 우리는 상태코드 값을 설정할 수 있습니다. 그럼 상속된 클래스인 HttpEntity는 어떤 필드를 가질까요?
HttpEntity는 2️⃣header와 3️⃣body를 필드로 갖고 있습니다.
따라서 우리는
ResponseEntity
에 status, header, body 를 전달하고 생성하여 응답 데이터를 클라이언트로 보낼 수 있습니다.ResponseEntity 적용 해보기
최초에 ResponseEntity를 적용했을 때 new 생성자를 통해 클라이언트로 return 해주었습니다.
그러고 코드리뷰를 하면서, ResponseEntity를 new 생성자 대신 Buider 패턴을 통해 생성하면 더 유용하게 사용할 수 있다는 점을 알게 되었습니다. 먼저 아래와 같은 Builder 패턴 자체의 장점들을 고스란히 가져갈 수 있습니다.
- 유연하게 값을 설정할 수 있음.
- 가독성 측면에서 좋다.
제일 좋았던 점은 2번째 항목인(가독성 측면)도 얼추 포함되는 내용인데 ResponseEntity의 생성자가 갖는 매개변수 순서를 굳이 외울 필요가 없다는 점입니다.
따라서 위 코드와 같이 작성된 부분을 builder 패턴을 사용하는 방식으로 리팩토링을 진행하였습니다.
+추가)
ResponseEntity 내부 코드를 보게 되면
자주 사용되는 Http 상태 코드를 이름으로 갖는 메서드가 선언되어 있습니다.
그래서 자주 사용되는 Http 상태 코드를 사용할 때에는, 위 메서드를 통해 Http 상태 코드를 정해줄 수 있고, builder 패턴을 통해 body나 header 값도 정할 수 있습니다.