HTTP QUERY 메서드 완벽 정리: RFC 10008, QUERY와 GET·POST 비교

RFC 10008은 요청 본문에 쿼리를 담아 전달하는 안전하고 멱등적인 HTTP 메서드인 QUERY를 정의한다. 명세가 Content-Type, 캐싱, Location, Accept-Query에 관해 설명하는 내용, QUERY가 GET 및 POST와 비교되는 방식, 그리고 오늘날 이를 지원하는 대상.

Ashley Innocent

Ashley Innocent

28 October 2026

HTTP QUERY 메서드 완벽 정리: RFC 10008, QUERY와 GET·POST 비교

Apidog 엔터프라이즈

온프레미스 배포

SSO & RBAC

SOC 2 준수

Apidog Enterprise 살펴보기

HTTP QUERY 메서드는 RFC 10008(2026년 6월)에 정의된 새로운 요청 메서드로, 요청 본문에 쿼리를 담아 전송하며 안전(safe)하면서도 멱등(idempotent)합니다. 본문이 있는 GET이라고 생각하면 됩니다. POST처럼 복잡한 필터를 담을 공간을 확보하면서도, GET이 제공하는 캐싱과 자동 재시도의 보장을 함께 얻을 수 있습니다.

3KB짜리 필터를 URL에 억지로 밀어 넣어본 적이 있거나, 읽기 전용 검색을 POST로 보내면서 캐시와 재시도 로직이 이를 무시하는 모습을 지켜본 적이 있다면, QUERY가 그 해결책입니다. 이 가이드에서는 명세가 정의하는 내용, QUERY가 GET 및 POST와 어떻게 비교되는지, 현재 무엇이 이를 지원하는지, 그리고 코딩 에이전트로 QUERY 엔드포인트를 테스트하는 방법을 다룹니다.

HTTP QUERY 메서드란 무엇인가?

QUERY는 대상 리소스에 요청 콘텐츠에 설명된 쿼리를 실행하고 그 결과를 반환하도록 요청하는 HTTP 메서드입니다. 요청 본문과 그 Content-Type이 쿼리를 정의합니다. 이 메서드는 안전하고(클라이언트는 상태 변경을 기대하지 않음) 멱등하므로(반복해도 동일한 효과), 클라이언트, 프록시, 캐시가 GET처럼 재시도하고 캐시할 수 있습니다.

명세는 RFC 10008, “The HTTP QUERY Method”로, Julian Reschke(greenbytes), James M. Snell(Cloudflare), Mike Bishop(Akamai)이 2026년 6월에 발표한 제안 표준(Proposed Standard)입니다. IANA는 이를 HTTP 메서드 레지스트리에 “safe: yes, idempotent: yes”로 등록했으며, 거의 채택될 뻔했던 WebDAV 시대의 SEARCH 메서드 바로 옆에 자리 잡았습니다.

QUERY 요청은 다음과 같습니다:

QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
Accept: application/json

select=surname,givenname,email&limit=10&match=%22email=*@example.*%22

서버는 200 OK와 함께 본문에 결과를 담아 응답합니다.

GET과 POST로는 충분하지 않았던 이유

QUERY 이전에는 복잡한 읽기 작업을 위한 두 가지 선택지가 있었고, 둘 다 문제가 있었습니다.

GET은 모든 것을 URL에 담습니다. RFC 10008은 이 방식의 네 가지 문제를 나열합니다:

  1. 요청이 여러 시스템을 거치기 때문에 크기 제한을 미리 알 수 없습니다. RFC 9110은 송신자와 수신자가 최소 8,000 옥텟을 지원할 것을 권장할 뿐입니다.
  2. 구조화된 데이터를 유효한 URI로 인코딩하는 것은 낭비입니다.
  3. URI는 요청 본문보다 훨씬 자주 로깅되고 북마크되므로, 민감한 필터에는 프라이버시 문제가 됩니다.
  4. 쿼리 입력의 모든 조합이 각각의 리소스가 됩니다.

본문이 있는 GET도 답이 아닙니다. RFC 9110은 GET 요청의 콘텐츠에 정의된 의미가 없다고 명시합니다. 일부 서버는 이를 읽고, 일부는 무시하며, 일부 프록시는 요청을 거부합니다. 전체 경로에서 이를 신뢰할 수 없습니다.

POST는 작동하지만 의도를 잘못 전달합니다. POST 검색은 잘 실행되지만, 클라이언트, 캐시, 프록시, 재시도 라이브러리에 이 작업이 읽기 전용임을 알려주지 않습니다. 그래서 캐시는 이를 건너뛰고, 클라이언트는 연결이 끊긴 후 재시도하지 않습니다. 순수한 읽기 작업에 재시도를 안전하게 만들기 위해 멱등성 키를 억지로 붙여야 했던 적이 있다면, 이 문제를 이미 체감하셨을 것입니다.

QUERY는 POST의 본문을 유지하면서 GET의 보장을 추가합니다.

QUERY vs GET vs POST

RFC 10008의 표 1을 기반으로 한 비교는 다음과 같습니다:

속성 GET QUERY POST
안전(Safe) 예 예 아닐 수 있음
멱등(Idempotent) 예 예 아닐 수 있음
요청 본문 정의된 의미 없음 필수, 쿼리를 정의함 필수
쿼리 자체를 위한 URI 예, 정의상 선택적, Location을 통해 아니오
결과를 위한 URI 선택적, Content-Location을 통해 선택적, Content-Location을 통해 선택적, Content-Location을 통해
캐시 가능 예 예, 본문이 캐시 키의 일부임 이후 GET 또는 HEAD에 대해서만
브라우저의 CORS 프리플라이트 단순 요청에는 불필요 항상 발생 단순 요청에는 불필요

요약하자면: 쿼리가 URL에 편안히 들어가면 GET을, 그렇지 않으면 QUERY를 사용하고, 요청이 상태를 변경할 때만 POST를 사용하세요. 전통적인 메서드에 대한 복습은 HTTP 메서드와 GET vs POST 가이드를 참고하세요.

RFC 10008이 정의하는 내용

Content-Type은 필수

서버는 Content-Type이 누락되었거나 본문과 일치하지 않는 QUERY를 반드시 실패시켜야 합니다(MUST). RFC는 다음과 같은 상태 코드를 권장합니다:

Location과 Content-Location

서버는 QUERY를 나중에 GET할 수 있는 것으로 바꿔주는 두 가지 선택적 헤더를 반환할 수 있습니다:

RFC는 반복 요청에는 GET 캐싱이 더 단순하기 때문에 클라이언트가 Location URI로 GET을 전환할 것을 제안합니다. 민감한 데이터가 있는 쿼리에 이 두 헤더 중 하나를 반환하는 경우, 해당 URI에는 원본 본문의 민감한 부분이 포함되어서는 안 됩니다(SHOULD NOT).

캐싱

QUERY 응답은 캐시 가능합니다. 캐시 키에는 요청 콘텐츠와 미디어 타입 같은 관련 메타데이터가 반드시 포함되어야 합니다(MUST). 캐시는 더 많은 적중을 얻기 위해 먼저 본문을 정규화할 수 있습니다(MAY). 예를 들어 콘텐츠 인코딩을 제거하거나 +json 타입에 대해 JSON을 정규화하는 식입니다. 명세는 잘못된 정규화가 잘못된 응답을 반환할 수 있다고 경고하므로, CDN이 이 부분에서 신중할 것으로 예상됩니다.

리다이렉트

301, 302, 307, 308은 “동일한 QUERY를 새 URI로 보내라”는 의미입니다. POST와 달리 QUERY는 301이나 302에서 GET으로 재작성되어서는 안 됩니다. 303 See Other는 “이 URI에 GET으로 결과를 가져오라”는 의미입니다.

Accept-Query 헤더

Accept-Query는 QUERY 지원과 리소스가 허용하는 쿼리 형식을 알려주는 새로운 응답 헤더입니다. 구조화 필드(Structured Field) 목록이므로 그에 맞게 파싱하세요:

Accept-Query: "application/jsonpath", application/sql;charset="UTF-8"

클라이언트는 OPTIONS로 지원 여부를 확인하고 Allow 헤더를 읽거나, 그냥 QUERY를 보내고 405 Method Not Allowed를 처리할 수도 있습니다.

현재 어떤 도구가 QUERY를 지원하는가?

지원 현황은 고르지 않으므로 자신의 스택을 직접 테스트해야 합니다. 2026년 10월 28일에 확인한 내용은 다음과 같습니다:

도구 결과
Node.js 24 http 서버 http.METHODS에 QUERY가 포함됨; 일반 서버가 메서드와 본문을 수신함
Node.js 24 fetch JSON 본문과 함께 QUERY를 전송함
curl 8.7 -d와 함께 curl -X QUERY가 메서드와 본문을 전송함
Python 3.14 http.client 본문과 함께 QUERY를 전송함
OpenAPI 3.2 Path Item Object에 QUERY 작업을 위한 query 필드가 있음
Apidog CLI 2.2.12 endpoint-create 스키마가 "method": "query"를 허용함

로컬 Node 서버에 사용한 curl 호출은 다음과 같습니다:

curl -i -X QUERY http://localhost:3000/products \
  -H "Content-Type: application/json" \
  -d '{"q":"running shoe","limit":2}'

Fetch 표준은 GET과 HEAD에 대해서만 본문을 금지하므로, 브라우저는 본문과 함께 QUERY를 보낼 수 있습니다. 하지만 QUERY는 CORS 안전 목록 메서드가 아니므로 모든 교차 출처 QUERY는 프리플라이트를 트리거합니다. 서버는 Access-Control-Allow-Methods에 QUERY를 포함해야 합니다.

문제는 네트워크 중간에 있습니다: 메서드를 허용 목록에 추가하거나 캐시를 본문 기준으로 키잉하지 않는 리버스 프록시, API 게이트웨이, WAF, CDN 등입니다. 배포 전에 각 홉을 확인하세요. APIs You Won’t Hate 뉴스레터는 많은 웹 프레임워크가 이미 QUERY를 직접 또는 커스텀 메서드 라우팅을 통해 처리한다고 언급합니다.

클라이언트를 깨뜨리지 않고 QUERY를 도입하는 방법

POST 검색 엔드포인트를 전부 걷어낼 필요는 없습니다.

  1. POST 라우트와 함께 QUERY를 추가하세요. 둘 다 같은 핸들러를 가리키게 하세요. 새 클라이언트는 QUERY를 사용하고, 기존 클라이언트는 계속 작동합니다.
  2. 알리세요. 리소스에 Accept-Query를 반환하고, OPTIONS 및 405 응답의 Allow에 QUERY를 포함하세요.
  3. Content-Type을 강제하세요. RFC가 권장하는 대로 400 또는 415를 반환하고, 파싱은 되지만 실행할 수 없는 쿼리에는 422를 반환하세요.
  4. 405 또는 501로 폴백하세요. 어떤 홉이 QUERY를 거부하면 클라이언트는 같은 본문을 POST로 재시도해야 합니다.
  5. CORS를 수정하세요. 브라우저 클라이언트를 위해 Access-Control-Allow-Methods에 QUERY를 추가하세요.
  6. 캐싱을 결정하세요. 캐시가 본문을 기준으로 키잉하는 경우에만 공유 캐싱을 활성화하세요. 그렇지 않으면 Location URI를 반환하고 클라이언트가 GET하도록 하세요.
  7. 문서화하세요. OpenAPI 3.2에서는 경로 항목의 query: 아래에 작업을 정의하세요:
openapi: 3.2.0
paths:
  /products:
    query:
      summary: Search products
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductQuery'
      responses:
        '200':
          description: Matching products

짧고 단순한 필터는 GET의 쿼리 문자열로 남겨둬도 됩니다. RFC 10008 자체도 쿼리가 그렇게 짧다면 GET이 더 나은 선택일 가능성이 크다고 말합니다.

Apidog CLI로 코딩 에이전트가 QUERY 엔드포인트를 테스트하게 하세요

새로운 메서드는 해피 패스, 모든 에러 코드, 폴백 라우트를 확인해야 한다는 뜻입니다. 이를 Claude Code, Codex 또는 Cursor에 맡기고 Apidog CLI를 구동하게 하세요.

CLI를 설치하고 로그인한 다음, 에이전트에 Apidog 스킬을 추가하세요:

npm install -g apidog-cli@latest
apidog login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com   # pick your agent when prompted

그런 다음 에이전트에 프롬프트 하나를 주세요:

In Apidog project <projectId>, add a QUERY /products endpoint that takes a
JSON body {q, limit}. Create test cases that assert 200 with an array for a
valid body, 415 for Content-Type text/plain, and 400 with no Content-Type.
Run them against the staging environment and summarize any failures.

에이전트는 각 스키마를 읽고 페이로드를 검증한 다음에야 다음과 같이 작성합니다:

apidog cli-schema get endpoint-create
apidog cli-schema validate endpoint-create --file endpoint.json
apidog endpoint create --project <projectId> --file endpoint.json
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog test-case create --project <projectId> --file case.json
apidog run --test-case <caseId> --project <projectId> -e <envId> -r cli,json

에이전트가 작성하는 endpoint.json은 "method": "query"를 설정하며, CLI의 endpoint-create 스키마는 이를 get, post 및 WebDAV 메서드와 함께 나열합니다. Apidog 앱에서 실행 결과를 보려면 --upload-report를 추가하세요. -r junit을 붙인 동일한 apidog run 명령은 CI에 바로 통합됩니다. 자세한 내용은 apidog run으로 CI에서 API 테스트를 실행하는 방법과 Claude Code에서 Apidog CLI를 사용하는 방법을 참고하세요. Apidog의 무료 플랜은 최대 4명의 사용자까지 지원합니다.

FAQ

HTTP QUERY 메서드는 공식 표준인가요? 예. RFC 10008은 2026년 6월에 발표된 Standards Track, Proposed Standard RFC이며, IANA는 QUERY를 HTTP 메서드 레지스트리에 안전하고 멱등한 메서드로 등록했습니다.

QUERY는 그냥 본문이 있는 GET인가요? 비슷하지만 더 잘 정의되어 있습니다. RFC 9110은 GET 본문에 아무 의미도 부여하지 않으므로 중개자가 이를 무시하거나 거부할 수 있습니다. QUERY는 본문을 쿼리로 만들고, Content-Type을 요구하며, 본문을 캐시 키에 포함시킵니다.

POST 대신 언제 QUERY를 사용해야 하나요? URL에 담기에는 너무 크거나 너무 민감한 모든 읽기 전용 검색이나 필터에는 QUERY를 사용하세요. 무언가를 생성하거나 변경하는 요청에는 POST를 유지하세요.

브라우저가 QUERY 요청을 보낼 수 있나요? 예, 커스텀 메서드와 함께 fetch를 통해 가능합니다. 교차 출처 QUERY 요청은 항상 CORS 프리플라이트가 필요하므로 서버가 이 메서드를 허용해야 합니다.

QUERY 응답은 캐시되나요? 캐시될 수 있습니다. 캐시는 요청 본문과 그 메타데이터를 캐시 키에 포함해야 합니다. 많은 CDN과 프록시가 아직 이를 수행하지 않으므로, 자신의 것을 확인하거나 클라이언트가 GET할 수 있는 Location URI를 반환하세요.

OpenAPI가 QUERY를 지원하나요? OpenAPI 3.2는 QUERY 작업을 위해 Path Item Object에 query 필드를 추가하므로, 확장 없이 문서화할 수 있습니다.

Apidog에서 API 설계-첫 번째 연습

API를 더 쉽게 구축하고 사용하는 방법을 발견하세요

HTTP QUERY 메서드 완벽 정리: RFC 10008, QUERY와 GET·POST 비교