brunch

You can make anything
by writing

C.S.Lewis

by 강관우 May 24. 2021

HTTP GET 메소드와 body

GET메소드에 body 를...

RESTful API를 설계함에 있어 HTTP GET 메소드는 URI에 해당하는 리소스를 조회하는 용도로 사용된다.

때문에 여기에 추가되는 API 파라미터들은 조회 조건을 설정하기 위해 사용하는 경우가 일반적이므로 Path Parameter 혹은 Query Parameter를 통한 설계가 이뤄진다.


하지만 body 안에 조회조건을 넣어 GET 메소드를 설계하는 경우가 생길 수 있다. 복잡한 조회 조건을 JSON 혹은 XML을 통해 서버로 보내려고 할 때, GET 메소드에 body entity를 추가하는 것은 스펙상 문제가 없을까?


RFC2616

2014년 이전에 HTTP 1.1 스펙으로 여겨지던 RFC2616 문서에는 아래와 같은 문구가 있다.


...if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.


여기서 SHOULD의 의미는 RFC2119 문서에 의거하여 RECOMMENDED로 해석된다.


그리고 이 스펙에서 GET 메소드에 대한 설명은 아래와 같다.

The GET method means retrieve whatever information ([...]) is identified by the Request-URI.

https://datatracker.ietf.org/doc/html/rfc2616#section-9.3

https://datatracker.ietf.org/doc/html/rfc2616#section-4.3


GET 메소드에 대한 설명과 entity-body에 대한 언급으로 볼 때 GET 메서드가 반환하는 리소스들은 URI에 근거하는 것이 의미론적으로 맞아 보인다. 


RFC 7230-7237

하지만 2014년 이후에 나온 RFC 7230-7237 스펙에서 "the message-body SHOULD be ignored when handling the request." 문구와 "The GET method means retrieve whatever information ... is identified by the Request-URI" 문구가 삭제됐다. 


대신 "Request message framing is independent of method semantics, even if the method doesn't define any use for a message body" 라는 문구가 추가됐는데, 이는 method 의미와 request body의 의미 체계는 독립적이라고 해석된다.


2014년 이후 나온 스펙을 본다면 GET 메소드에 body 값을 실어 요청을 보내는 게 큰 무리가 없어 보인다.


사용할 수 있을까?


사용할 수도 있고 못할 수도 있다. 


스펙을 다양한 의미로 해석할 수 있고, 대부분의 HTTP client에서도 GET with body를 허용하는 것처럼 API를 설계하는 철학에 따라서 또는 요구사항에 따라서 GET 메서드에 body 값을 추가할 수 있다. 


몇 가지 주의 사항을 알아보자


# 캐싱, 프록시

캐싱이나 프록시 설계 중 일부는 GET의 body 값을 참조하지 않는 경우가 있다. GET 캐싱 기능을 기대하며 body에 쿼리 조건을 넣는 경우 문제가 생긴다.


# RESTful Semantics

 Semantic은 다른 구성원들이 이 컴포넌트가 디자인된 철학대로 구현됐을 거라 기대하는 것을 말한다. 통용되는 의미론을 무시한다면 시스템 설계가 산으로 갈 가능성이 있다.


# 지원하지 않는 Client

Spring RestTemplate의 경우 GET 메서드를 사용하는 경우 body 값을 보내지 않고 있다. 이처럼 특정 클라이언트 혹은 서버에서는 GET body가 무시되는 경우가 왕왕 있으므로 주의해야 한다.

 

하지만 위 주의사항으로 HTTP GET 메서드에서 body entity를 활용하는 것을 지양한다면, 

이 자체가 RFC 7230-7237 스펙 위반이 될 수 있다. 


URI로 표현할 수 없는 복잡한 조회 조건을 가진 경우, body entity를 어쩔 수 없이 사용해야 할 수도 있는데, 실제로 엘라스틱서치를 포함한 다양한 애플리케이션에서 GET method에 body 값을 포함하는 경우를 볼 수 있다.


여러 주의사항과 사용 사례로 볼 때, 어떻게 설계할지는 시스템 요구사항에 따라 달라진다.

개인적으로 URI로 표현 가능하다면 URI에 실어서 보내는 것을 권장하지만 조회 조건이 길어진다면 body 값을 사용하는 것도 고려해볼 수 있을 것 같다.






브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari