티스토리 뷰

Network

HTTP QUERY 메서드

LichKing 2026. 6. 28. 14:33

조회 API 를 만들어야한다면 어떤 메서드를 써야할까? 다들 몇초 걸리지 않아 GET 이라고 답할 것이다.

GET /members/928

위와 같이 리소스 id 로 접근하는 경우 GET 으로 만드는데 아무런 어려움이 없다. 리소스 id 가 아니라 다른 조건으로 조회를 해야한다면 어떻게 할 수 있을까?

GET /members?name={name}

이런식으로 query string 을 사용해 표현할 수 있다. 보통은 이정도 수준으로 조회 API 를 설계한다. 하지만 조회 조건이 복잡해지는 경우 query string 을 써야할지 고민이 되는 경우가 있다.

GET /members?param1={param1}&param2={param2}&param3={param3}&param4={param4}&param5={param5}

이런 경우 url 이 지저분해지다보니 뭔가 직관적으로 마음에 들지 않고, 다른 방안을 고민해보게 된다.

 

# POST + body

몇가지 방안이 있겠지만 HTTP 메서드를 POST 로 변경해서 request body 를 사용하는 방법이다. 이렇게하면 깔끔한 url 을 유지할 수 있다.

POST /members
Content-Type: application/json

{
  "param1": {param1},
  "param2": {param2},
  "param3": {param3},
  "param4": {param4},
  "param5": {param5}
}

이 방식은 깔끔한 url 을 유지할 수 있지만 몇가지 단점이 있다.

 

- 조회조건 공유 불가

내 조회결과를 상대방한테 전달할때 조회조건을 같이 전달할 수 없다. 네이버나 구글에서 검색한뒤 해당 결과를 공유하고 싶을때 url 을 전달해봤자 상대방은 네이버나 구글의 메인페이지를 보게된다.

 

- HTTP cache 불가

HTTP 스펙엔 cache 스펙이 있다. cache 스펙에 따르면 cache key 에  request body 는 필수포함이 아니기 때문에 cache 를 적극적으로 활용하기 어렵다. request body 가 달라져도 동일한 요청으로 간주하기 때문이다.

 

- API 의도 불명확

POST 는 내부 상태를 변경할때 사용한다. 단순 조회인 경우 내부 상태를 변경하지 않고, 그렇기에 멱등성을 지키지만 POST 로 구현되어 있다면 이런 내용을 스펙으로 드러낼 수 없다.

 

# GET + body

GET /members
Content-Type: application/json

{
  "param1": {param1},
  "param2": {param2},
  "param3": {param3},
  "param4": {param4},
  "param5": {param5}
}

그냥 request body 사용하면 되지 메서드를 변경할 필요있나? GET 에다가 request body 를 사용하는 방법이다.

개인적인 생각에 이 방식은 상당한 테토방식인데, 이 방식은 POST + body 에서 설명했던 단점 중 API 의도 불명확을 해소할 수 있다. GET 메서드이기 때문에 조회전용임을 드러낼 수 있기 때문이다. 다만 나머지 2가지 단점은 여전히 해결할 수 없다.

 

이 방식은 추가적으로 다른 문제가 한가지 있는데 RFC 스펙에서 GET + body 를 권장하지 않는다는 것이다( https://www.rfc-editor.org/rfc/rfc9110.html#name-get ). 해당 스펙에서 클라이언트는 GET 요청시 body 를 추가하지 않는걸 권장한다고 한다. 예외적으로 서버가 GET body 를 허용한다고 정의했을때만 추가할 수 있고, 이 경우에도 클라이언트와 서버가 직접 통신하는 경우에만 사용할 수 있다고 정의한다. 왜냐하면 직접 통신이 아니라 중간에 다른 홉들이 있게되면 해당 홉에서 뒷단으로 body 전달을 보장하지 않기 때문이다. 일반적인 api 를 만들땐 GET 에 body 를 고려하지 말라는 의미다.

 

왜 스펙을 이리 애매하게 정의했을까를 고민해보면 이미 GET 요청에서 body 를 처리하는 서버들이 있기 때문에 하위호환을 위해 어쩔 수 없이 허용한게 아닐까 싶다.

 

# GET + query string

굳이 이렇게 단점들을 감수하고 body 를 쓰려고 할 필요있나? 그냥 기존대로 GET 을 쓰는 방안이다. url 이 길어진다고? 좀 길어질수도 있지 그게 쓰지 못할 이유가 되지 않는다.

 

간혹 파라미터가 너무 길면 길이제한에 걸린다고 주장하는 경우가 있으나 실제로 이로인해 문제가 생기는 경우는 거의 없다. 톰캣이나 nginx 를 비롯한 많은 서버는 기본적으로 8KB 를 지원하고 있기 때문에 조회 조건 좀 추가한다고 쉽게 넘기기 어렵기 때문이다. 다만 8KB 제한은 url 에 한해서만 제한하는게 아니라 헤더를 포함한다. 그래서 간혹 쿠키 관리를 잘못할 경우 이 제한에 걸리는 경우를 본적이 있다. 그럴땐 쿠키 관리 로직을 확인하거나, 8KB 제한을 늘려서 해결할 수 있다. 이 경우에도 일반적인 조회 조건 갯수가 이슈가 되는 경우는 본적 없다. 이 방안으로 갈 경우 위에서 언급한 모든 단점들이 싹 사라진다.

 

이 방안의 문제는 딱 하나다. 조회 조건에 민감한 정보들이 포함되는 경우다. 민감 정보가 문제라면 TLS 를 사용하여 데이터를 보호할 일이지 민감한 정보들을 query string 이 아니라 body 에 넣는다고 안전해지는게 있냐고 반박할 수 있다. 맞는 말이다. 하지만 보통 기업에서 많은 사용자들을 처리할때 요청 데이터는 다양한 서버를 통해 실제 처리 서버로 도달한다. 그리고 일정 수준 이후부터는 평문화된 요청 메시지를 전달한다. 그러면 웹서버들은 액세스 로그를 남기게 되는데, 이때 query string 은 url 로 보기 때문에 모든 정보가 로그로 남게된다. 이 경우 민감 정보가 로그로 남는 문제가 발생하는 것이다. 참고로 body 는 로그를 남기지 않기 때문에 문제가 없다. 이 문제가 조회 조건을 body 로 보내는걸 고민하게 되는 지점이다.

 

# QUERY

이런 문제를 모두 해소하기 위해 신규 HTTP 메서드가 추가됐다. 바로 QUERY 메서드이다. 2026년 6월에 발표된 따끈따끈한 스펙이다. QUERY 메서드는 공식적으로 조회 조건을 body 에 첨부할 수 있다.

QUERY /members
Content-Type: application/json

{
  "param1": {param1},
  "param2": {param2},
  "param3": {param3},
  "param4": {param4},
  "param5": {param5}
}

위에서 얘기했던 조회 조건을 body 에 넣는 경우 단점에 대해 알아보자.

 

- 조회 조건 공유 불가

이 단점은 QUERY 를 사용해도 여전하다. 이 때문에 조회 조건 공유가 꼭 필요하다거나 민감한 정보가 아니라면 가급적 GET 을 쓰는게 좋다.

 

- HTTP cache 불가

QUERY 메서드의 요청은 request body 까지 포함해서 cache key 로 활용하는게 스펙이다. 이 때문에 body 가 달라지는 경우에 대한 cache 가 가능하다. 물론 이를 구현하기 위해 cache 구현시 request body 까지 읽어야하는 비용이 추가됐다.

 

- API 의도 불명확

QUERY 는 그 자체로 조회를 나타내며, 이 때문에 안전하고 멱등성 제공을 드러낼 수 있다.

 

- 민감 정보 로깅

민감 정보를 body 에 담을 경우 액세스 로그 등에 남지 않으므로 좀 더 편안하게 사용할 수 있다.

 

# 마무리

QUERY 를 사용하더라도 조회 조건 공유는 할 수 없다. 이 때문에 조회 조건 공유가 필요하다면 GET 을 사용하는게 좋다.

조회 api 설계시 일단은 GET 으로 구현하는걸 1순위로 생각하고, 민감 정보 포함과 같은 문제가 발생시 QUERY 사용을 후순위로 고려해보는게 좋을 것 같다.

'Network' 카테고리의 다른 글

post vs put  (6) 2019.04.10
robots.txt  (2) 2018.01.01
프록시 관련 HTTP header  (0) 2017.12.20
HTTP 메세저 형식  (0) 2017.12.04
Response Code  (0) 2016.11.14
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함