[Spring] GET Method에 RequestBody 요청 적합한가?
HTTP 메서드 중 GET 메서드에서는 보통 URL 쿼리 파라미터를 통해 데이터를 전달한다.
POST와 PUT 같은 메서드는 RequestBody 를 활용하는 것과는 차이가 있다.
왜 그런걸까?
GET 메서드에 RequestBody를 포함하는 것은 HTTP 표준에 맞지 않는다.
이에 관련된 관련 문서들을 찾아본 결과 다음과 같다.
RFC 7231 문서에서는 GET 요청 메시지 내 Payload(Body)에 대해 정의된 의미가 없음을 명시하고 있다.
- 이 말은 즉, 정의된 의미가 없기 때문에 서버에서 무시한다는 의미로 해석할 수 있다.
- 이러한 설계는 GET의 목적이 URL 및 쿼리 매개변수를 통해 리소스를 검색하는 것이지 POST와 달리 데이터를 제출하는 것이 아니기 때문
(출처: RFC 7231- HTTP/1.1 Semantics and Content)
// 대충 번역하면...
GET 요청 메시지 내의 페이로드는 정의된 의미가 없으며,
GET 요청에 페이로드 본문을 포함하는 것은
일부 기존 구현에서 요청을 거부하게 만들 수 있습니다.
RFC 9110 HTTP 문서에서도 관련 사항에 대해 추가 언급이 있다.
( 출처: RFC 9110 - HTTP Semantics)
// 대충 번역하면..
요청 메시지 프레이밍은 사용된 메서드와 독립적이지만,
GET 요청에서 받은 콘텐츠는 일반적으로 정의된 의미가 없으며,
요청의 의미나 대상을 변경할 수 없고,
일부 구현에서는 요청 밀어넣기 공격(레거시 보안 문제)으로 인해
요청을 거부하고 연결을 종료할 수 있습니다.
클라이언트는 GET 요청에서 콘텐츠를 생성하지 말아야 하며,
만약 그것이 특정 서버에서 지원될 수 있다는 표시가 없는 경우에는
GET 요청에 본문을 포함하지 말아야 합니다.
OpenAPI 사양(OAS 3.) 에서는 GET, DELETE, HEAD 요청이 RequestBody를 가질 수 없음을 명시하고 있다.
( 출처: OpenAPI Specification - OAS 3.0)
// 대충 번역하면..
GET, DELETE, HEAD는 RFC 7231에 따라 요청 본문을 가질 수 없습니다
*RFC 7231: HTTP/1.1의 의미와 콘텐츠에 관한 RFC (Request for Comments) 문서, HTTP 메서드의 의미와 사용에 대한 규격을 정의한 공식 문서
*RFC 9110: HTTP/1.1 및 HTTP/2의 의미와 콘텐츠에 대한 RFC 문서. 최신 HTTP의 표준을 다루고 있으며, GET 요청에 본문을 포함하는 것에 대해 다룬 문서
*OpenAPI Specification (OAS 3.0): OpenAPI 사양을 정의하는 공식 문서, API 문서를 작성할 때 RESTful API의 메서드 사용 규칙과 요청 본문에 대한 내용을 다룬 문서
정리
- GET 요청에서 본문을 포함하는 것은 기술적으로 가능하지만,
HTTP 표준에 맞지 않으며, 보안, 호환성 및 캐싱 측면에서 문제가 될 수 있다 - 따라서, GET 요청에는 요청 본문을 사용하지 않는 것이 좋으며,
만약 요청 본문이 필요한 경우 POST, PUT 등의 메서드를 사용하는 것이 RESTful한 방식이다.'
참고 내용
HTTP GET Requests and Message Bodies: Standards, Changes, and Concerns
Background: GET Requests in the Original HTTP Standard
medium.com
추가 내용
과거, 초기 HTTP 표준에서는 GET 메서드가 순전히 검색 요청으로 정의되어 있어 HTTP/1.1 사양(RFC 2616, 1999)에서는 GET 및 HEAD와 같은 메서드가 엔티티 본문을 포함해서는 안된다고 명시되어 있었다.
- RFC 2616 states:
“A message-body MUST NOT be included in a request if the specification of the request method … does not allow sending an entity-body in requests.”
다만, 시간이 지나면서 HTTP 사양이 개선됨에 따라 RFC 7231(2014)에서
- 본문을 완전히 금지하지는 않지만 기본적으로 정의된 의미가 없어 GET 요청에 Payload 본문을 보낼 경우 일부 기존 구현에서 요청을 거부할 수 있다
정도의 표현으로 완화되었다.