# RFC 10008: 새로운 HTTP QUERY 메서드

> Clean Markdown view of GeekNews topic #30594. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=30594](https://news.hada.io/topic?id=30594)
- GeekNews Markdown: [https://news.hada.io/topic/30594.md](https://news.hada.io/topic/30594.md)
- Type: GN+
- Author: [xguru](https://news.hada.io/@xguru)
- Published: 2026-06-18T09:59:40+09:00
- Updated: 2026-06-18T09:59:40+09:00
- Original source: [rfc-editor.org](https://www.rfc-editor.org/info/rfc10008/)
- Points: 1
- Comments: 1

## Topic Body

- RFC 10008은 요청 본문에 담긴 질의를 대상 리소스가 **안전하고 멱등적으로 처리**한 뒤 결과를 반환하는 HTTP **QUERY 메서드**를 정의함
- QUERY는 GET의 safe/idempotent 성격과 POST의 본문 전달 방식을 결합해, 긴 URI·URI 인코딩 비용·로그 노출·질의 조합별 리소스화 부담을 줄임
- 서버는 QUERY 요청의 **Content-Type**과 본문이 일관되어야 처리할 수 있으며, 미지원 타입·본문 불일치·처리 불가능한 질의는 각각 다른 4xx 응답으로 구분될 수 있음
- 성공 응답은 **Content-Location**으로 질의 결과 리소스를, **Location**으로 같은 질의를 다시 수행할 equivalent resource를 알려줄 수 있음
- QUERY 응답은 캐시 가능하지만 캐시 키가 본문과 메타데이터까지 포함해야 하며, CORS 환경에서는 safelisted method가 아니어서 **preflight**가 필요함

---

### QUERY가 해결하려는 HTTP 질의 패턴
- RFC 10008은 HTTP **QUERY 요청 메서드**를 정의하는 Internet Standards Track 문서임
- QUERY는 대상 리소스가 요청 본문을 처리하고 그 결과를 응답하도록 요청함
- POST처럼 본문을 쓰지만 **safe**와 **idempotent**로 정의되어 자동 재시도나 재시작이 가능함
- 기존 GET 질의는 URI에 입력을 넣는 방식이 일반적임
  - `GET /feed?q=foo&limit=10&sort=-published HTTP/1.1`
- URI에 질의 데이터를 넣으면 데이터가 커질수록 제약이 커짐
  - 여러 독립 시스템을 거치기 때문에 실제 URI 크기 제한을 미리 알기 어려움
  - HTTP는 송신자와 수신자가 최소 **8000 octets**를 지원하도록 권장하지만, 경로상의 모든 시스템을 보장하지는 않음
  - 일부 데이터는 유효한 URI로 인코딩하는 비용이 큼
  - 요청 URI는 요청 본문보다 로그에 남거나 북마크에 포함될 가능성이 큼
  - 질의를 URI에 직접 인코딩하면 가능한 입력 조합마다 별도 리소스로 취급됨

### GET과 POST 사이의 의미를 명확히 하는 메서드
- 많은 구현은 GET 대신 POST 본문으로 질의를 전달함
  - `POST /feed`
  - `Content-Type: application/x-www-form-urlencoded`
  - 본문: `q=foo&limit=10&sort=-published`
- 이 방식은 특정 리소스와 서버 지식 없이는 안전하고 멱등적인 질의인지 드러나지 않음
- QUERY는 같은 입력을 요청 본문으로 보내면서도, 메서드 자체가 안전하고 멱등적임
  - `QUERY /feed`
  - `Content-Type: application/x-www-form-urlencoded`
  - 본문: `q=foo&limit=10&sort=-published`
- 이 명시적 의미 덕분에 캐싱과 자동 재시도 같은 HTTP 기능을 적용하기 쉬워짐
- 서버는 질의 자체나 특정 질의 결과에 URI를 부여해 이후 GET 요청에 사용할 수 있음

### QUERY 메서드의 핵심 규칙
- QUERY는 서버 측 질의를 시작하는 데 사용됨
- GET은 대상 URI가 식별하는 리소스의 표현을 요청하지만, QUERY는 대상 리소스 범위 안에서 **질의 작업**을 수행하도록 요청함
- 요청 본문과 미디어 타입이 질의를 정의하고, origin server가 대상 리소스를 기준으로 작업 범위를 정함
- 서버는 **Content-Type** 요청 필드가 없거나 요청 본문과 일치하지 않으면 요청을 실패시켜야 함
- 대상 URI의 query part는 모든 HTTP 메서드와 마찬가지로 질의 대상 리소스 식별에 참여함
  - 그 query part가 결과에 직접 영향을 주는지와 방식은 리소스별 동작이며 이 명세 범위 밖임
- QUERY는 대상 리소스 관점에서 안전함
  - 클라이언트는 대상 리소스 상태 변경을 요청하거나 기대하지 않음
  - 서버가 추가 정보를 조회할 수 있는 HTTP 리소스를 만드는 것은 금지되지 않음
- QUERY는 멱등적이어서 연결 실패 뒤 필요한 경우 재시도하거나 반복할 수 있음
- `200 OK` 응답은 질의가 성공적으로 처리되었고 결과가 응답 본문에 포함되었음을 나타냄

### 미디어 타입, 협상, 오류 처리
- QUERY 요청의 의미는 요청 본문과 **미디어 타입** 같은 관련 메타데이터에 따라 달라짐
- 본문과 메타데이터가 일관되지 않은 요청은 일반적으로 **4xx Client Error**로 거부해야 함
- 오류 처리는 요청이 어디에서 잘못됐는지에 따라 달라짐
  - 미디어 타입 정보가 없으면 요청이 정의상 잘못되었으므로 `400` 같은 4xx 상태 코드로 실패해야 함
  - 미디어 타입이 지정되었지만 리소스가 지원하지 않으면 `415 Unsupported Media Type`이 적절함
  - 미디어 타입이 원칙적으로 알려져 있어도 대상 리소스의 QUERY 의미가 없으면 `415` 대상이 됨
  - 미디어 타입이 실제 요청 본문과 맞지 않으면 `400 Bad Request`를 반환할 수 있음
  - 서버는 본문을 보고 미디어 타입을 추론해 누락되었거나 잘못된 값을 덮어쓰는 **content sniffing**을 할 수 없음
  - 타입과 본문은 맞지만 실제 질의 내용 때문에 처리할 수 없으면 `422 Unprocessable Content`를 사용할 수 있음
  - 문법적으로 올바른 SQL 질의가 존재하지 않는 테이블을 가리키는 경우가 `422` 예시임
  - 클라이언트가 `Accept`로 요청한 응답 미디어 타입을 리소스가 지원하지 않으면 `406 Not Acceptable`이 적절함
- `Accept-Query` 응답 필드는 클라이언트에 지원되는 질의 미디어 타입을 알려줄 수 있음

### equivalent resource, Content-Location, Location
- **equivalent resource**는 특정 QUERY 요청과 그 대상을 나타내고 GET 요청에 응답하는 리소스임
- equivalent resource는 요청 본문과 메타데이터를 모두 고려함
  - 본문의 미디어 타입 같은 representation metadata가 포함됨
- 서버는 equivalent resource에 URI를 부여할 수 있지만 필수는 아님
- 성공 응답은 **Content-Location** 헤더로 질의 결과에 해당하는 리소스 식별자를 포함할 수 있음
  - 클라이언트는 표시된 URI에 GET을 보내 방금 수행한 질의 작업의 결과를 가져올 수 있음
  - 해당 리소스는 임시일 수 있음
- 성공 응답은 **Location** 헤더로 QUERY 요청의 equivalent resource URI를 포함할 수 있음
  - 클라이언트는 질의 본문을 다시 보내지 않고 표시된 URI에 GET을 보내 같은 질의 작업을 반복할 수 있음
  - 이 URI도 임시일 수 있음
  - 이후 요청이 실패하면 클라이언트는 원래 QUERY 대상과 이전에 제출한 본문으로 다시 시도할 수 있음

### 리다이렉션과 조건부 요청
- 서버는 QUERY 요청에 대해 다른 URI로 사용자 에이전트를 리다이렉트하는 간접 응답을 선택할 수 있음
- `301 Moved Permanently`와 `308 Permanent Redirect`는 대상 리소스가 Location이 가리키는 다른 URI로 영구 이동했음을 나타냄
- `302 Found`와 `307 Temporary Redirect`는 대상 리소스의 임시 이동을 의미함
- 네 경우 모두 서버는 새 대상 URI로 유사한 **QUERY 요청**을 보내면 원래 요청을 수행할 수 있다고 제안함
- `301` 또는 `302` 뒤 POST를 GET으로 리다이렉트하는 예외는 QUERY 요청에는 적용되지 않음
- QUERY에 대한 `303 See Other`는 원래 질의를 Location이 가리키는 URI에 대한 일반 조회 요청으로 수행할 수 있음을 나타냄
  - HTTP에서는 새 대상 URI로 GET 요청을 보냄
- 조건부 QUERY에서 selected representation은 해당 QUERY 요청의 equivalent resource에 대한 GET과 같음
- 클라이언트는 조건부 헤더가 지정한 조건에서만 질의 결과를 응답으로 반환하도록 요청할 수 있음

### 캐싱과 Range 요청
- QUERY 메서드 응답은 캐시 가능하며, 캐시는 이후 QUERY 요청을 만족시키는 데 사용할 수 있음
- QUERY 요청의 **캐시 키**는 요청 본문과 관련 메타데이터를 포함해야 함
- 캐시는 캐시 키 생성을 위해 의미상 중요하지 않은 차이를 제거할 수 있음
  - content encoding 제거
  - `+json` 같은 미디어 subtype suffix가 나타내는 형식 관례에 따른 정규화
  - `Content-Type`이 나타내는 본문 의미에 따른 정규화
- 이런 변환은 오직 캐시 키 생성을 위한 것이며 요청 자체를 변경하지 않음
- 클라이언트는 `no-transform` 캐시 지시어로 이런 변환을 원하지 않는다고 표시할 수 있지만, 이 지시어는 advisory임
- QUERY 응답 캐싱은 GET보다 본질적으로 더 복잡함
  - 캐시 키를 결정하려면 요청 본문 전체를 읽어야 함
  - QUERY 응답이 Location으로 equivalent resource URI를 제공하면 클라이언트는 이후 GET으로 전환해 처리를 단순화할 수 있음
- QUERY의 Range Request 의미는 GET과 같음
- 작성 시점에 정의된 유일한 range unit인 Byte Range Request는 QUERY 결과에는 가치가 작음
- SQL의 `FETCH FIRST ... ROWS ONLY`처럼 질의 형식 자체가 결과 제한이나 페이지네이션을 제공하는 경우가 많으며, 이런 내장 기능 사용이 기대됨

### Accept-Query 응답 헤더
- **Accept-Query** 응답 헤더는 리소스가 QUERY 메서드를 지원함을 직접 알리고 사용할 수 있는 질의 형식 미디어 타입을 식별함
- Accept-Query는 Structured Fields 문법을 사용하는 media range 목록임
- media range는 매개변수 없는 media range 값을 담은 Token 또는 String의 List Structured Header Field로 표현됨
- 미디어 타입 매개변수는 Structured Field Parameters로 매핑됨
  - String과 Token 선택은 의미상 중요하지 않음
  - 수신자는 Token을 String으로 변환할 수 있지만, 받은 타입에 따라 다르게 처리해서는 안 됨
- 미디어 타입은 Token과 정확히 매핑되지 않으며, 선행 숫자를 허용하는 경우에는 String 형식을 사용해야 함
- 지원되는 wildcard는 `*/*` 또는 `xxxx/*`뿐임
- 필드 값에 나열된 타입 순서는 중요하지 않음
- Accept-Query 값은 같은 path를 공유하는 서버의 모든 URI에 적용되며, query component는 무시됨
- 같은 리소스 요청이 다른 Accept-Query 값을 반환하면 가장 최근에 받은 fresh 값이 사용됨
- 예시는 다음과 같음
  - `Accept-Query: "application/jsonpath", application/sql;charset="UTF-8"`
- Accept-Query는 `Accept`와 비슷해 보이지만 Structured Field이므로 RFC 9651의 Structured Fields 처리 규칙을 따라야 함

### 보안 고려사항과 CORS
- QUERY는 RFC 9110에 정의된 모든 HTTP 메서드의 일반 보안 고려사항을 따름
- QUERY는 요청 정보를 URI query component에 넣는 방식의 대안으로 사용할 수 있음
- URI는 요청 본문보다 로그에 남거나 중개자에 의해 처리될 가능성이 커서, 민감한 정보가 포함된 질의에서는 GET보다 QUERY 사용 동기가 될 수 있음
- 서버가 QUERY 결과를 나타내는 임시 리소스를 만들고 URI를 부여할 때, 원래 요청 본문에 로그에 남기면 안 되는 민감 정보가 있으면 그 URI에 민감한 부분을 포함하지 않아야 함
- 캐시가 QUERY 본문을 잘못 정규화하거나 리소스 처리 방식과 크게 다르게 정규화하면 false positive로 잘못된 응답을 반환할 수 있음
- CORS를 구현하는 사용자 에이전트의 QUERY 요청은 **preflight** 요청이 필요함
  - QUERY는 CORS-safelisted methods 집합에 포함되지 않음

### IANA 등록과 메서드 이름 선택
- IANA는 QUERY 메서드를 HTTP Method Registry에 추가함
  - Method Name: `QUERY`
  - Safe: `yes`
  - Idempotent: `yes`
  - Specification: RFC 10008 Section 2
- IANA는 Accept-Query 필드를 HTTP Field Name Registry에 추가함
  - Field Name: `Accept-Query`
  - Status: `permanent`
  - Structured Type: `List`
- HTTP Method Registry에는 이미 safe와 idempotent 속성을 가진 `PROPFIND`, `REPORT`, `SEARCH`가 있었음
- 초기 단계에서는 `SEARCH`가 사용되었지만 최종 메서드 이름은 **QUERY**가 됨
- QUERY가 선택된 이유는 다음과 같음
  - 대안들은 요청 본문에 일반 미디어 타입 `application/xml`을 사용하고 요청 의미가 전적으로 본문에 의존함
  - 대안들은 모두 WebDAV 활동에서 비롯됨
  - `QUERY`는 URI의 query component와의 관계를 잘 포착함

## Comments



### Comment 59853

- Author: neo
- Created: 2026-06-18T09:59:41+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=48568502) 
- **강한 동기 부여 예시**가 있었다면 설득력이 더 컸을 텐데, 너무 쉽게 GET으로 표현할 수 있는 예시를 써서 오히려 산만해짐  
  큰 JSON 필터 구조나 이미지 입력을 요청 본문으로 넣는 QUERY를 상상해도, 요청 본문이 캐시 키의 일부가 된다는 건 매우 이상하게 느껴짐. 사용자 제어의 무한한 캐시 키가 생기고, 일반적인 캐싱 전략은 사실상 요청 본문을 비트 단위로 비교하거나 해시하는 것뿐이라 악의적 상황에서는 캐시 무효화가 아주 쉬워짐  
  복잡한 필터링이나 이미지 같은 복잡한 입력이 필요한 서비스를 만든다면, 캐싱은 HTTP 계층에서 멀리 떨어진 곳에 있을 가능성이 큼. 예를 들어 조인의 개별 데이터 컬럼이나, 디코딩된 이미지 입력의 지각 해시로 키를 잡은 임베딩처럼, 와이어상의 정확한 비트 표현과는 무관할 것임  
  이런 걸 왜 굳이 범용 방식으로 포착하려는지 모르겠음. 차라리 POST에 `"Vary: request-body"` 같은 새 헤더로 **캐싱 의미론**을 표현하는 편이 훨씬 낫다고 봄. 완전한 하위 호환이 되고, 이 동작이 유용할지도 모르는 0.1%의 CDN 용례 외에는 무시해도 됨
  - GET의 URI에 있는 **쿼리 부분**도 현실적으로는 거의 제한이 없고 사용자 제어이며, URI의 일부라 캐시 키에도 들어감. 그래서 이 반대가 왜 특별히 제기되는지 잘 모르겠음
  - 브라우저가 더 작은 캐시 키를 원한다면 본문의 **충돌 저항 해시**를 저장하면 됨. 예를 들어 SHA-256을 쓰면 됨  
    캐싱 관련 공격 중 쿼리 매개변수에도 똑같이 적용되지 않는 건 딱히 떠오르지 않음. 캐시를 넘치게 만들고 싶다면 고유한 30자 쿼리 매개변수를 만드는 것도 30MB 요청 본문을 만드는 것만큼 쉬움
  - 모든 사용 시나리오가 공개 인터넷인 건 아니고, 공개 인터넷에서 유용하지 않다고 해서 표준화할 수 없는 것도 아님  
    현실적으로 공개 인터넷용 시스템은 보안 해시를 캐시 키로 써서 항상 같은 크기로 만들 것임. 캐시 키에는 이미 아주 길 수 있는 URL과 임의의 헤더 값 집합도 포함됨
  - 이미지도 요청 본문으로 보낼 수 있지만, 이미 base64 쿼리 매개변수로도 할 수 있음. 마음먹고 이상하게 쓰면 어떤 제안 표준이든 나쁘게 사용할 수 있음  
    쿼리 매개변수가 있는 GET도 이미 불투명하고 **캐시 무효화**를 쉽게 만듦
  - 예를 들면 지금 작업 중인 데이터베이스용 **MCP 서버**를 만들고 있음. ChatGPT에서는 커밋 전에 롤백되는 dry-run POST를 먼저 하고 싶은데, 둘 다 속성 하나만 다른 POST 요청이라 도구의 안전 계층을 자주 건드림. 여러 이유로 정확한 원인을 디버깅하기도 어려움  
    하지만 QUERY 뒤에 POST를 두면 더 나아질 것 같음. 단순히 안전 플래그가 붙은 같은 요청이 아니라 서로 다른 요청 유형이 되기 때문임

- HTML 폼이 **QUERY 지원**을 추가할지 궁금함  
  QUERY는 멱등이어야 하므로, POST 폼 제출 결과 페이지를 새로고침할 때 뜨는 성가신 재제출 경고를 피할 수 있음
  - HTML 폼에서 GET/POST 말고 더 많은 메서드를 지원하는 건 수십 년간 바라던 일임. 마침 WHATWG 제안이 있으니 목소리를 보태고 싶다면 여기로 가면 됨: [https://github.com/whatwg/html/pull/11347](<https://github.com/whatwg/html/pull/11347>)
  - 폼의 이상한 점 하나는, 폼 POST의 결과가 위치(URL)를 가진 페이지이면서도 그 위치로는 로드할 수 없다는 것임. 아는 한 그 페이지가 GET이 아니라 POST라는 사실은 사용자나 JS가 볼 수 있는 곳에 저장되지 않고, 새로고침도 이상하게 동작함  
    `method=QUERY`가 추가되면 이런 이상함이 새 변종으로 하나 더 생김
  - 이건 **POST-Redirect-GET 패턴**으로 해결하는 편이 더 좋음
  - [https://github.com/whatwg/html/issues/12594](<https://github.com/whatwg/html/issues/12594>) 참고
  - 다른 동사 지원을 한 번도 추가하지 않았지만, 이제는 새로운 시대라 어떻게 될지 모름

- 아직도 지난 세기인 척하고 싶은 사람을 위해: [https://www.rfc-editor.org/rfc/rfc10008.txt](<https://www.rfc-editor.org/rfc/rfc10008.txt>)
  - 이런 길고 완전한 **일반 텍스트 문서**는 영원히 좋아할 듯함. 어릴 때 비디오 게임 FAQ를 보던 좋은 시절이 떠오름. 여러 면에서 정말 우월한 정보 형식임
  - **서식**이 아름다움. 내부 업무 메모용 스타일 템플릿으로 베껴 써야겠음. 시대를 타지 않음

- “GET 요청에 본문을 붙이는 방안은 IETF 작업반에서 깊이 검토됐지만, 결국 새 QUERY 메서드를 만드는 쪽으로 결정됐다. 별도 메서드를 만든 결정은 역사적 상호운용성 문제와 HTTP의 핵심 아키텍처 정의에 대한 엄격한 준수 때문이었다”  
  그런데 몇 년째 **GET 메서드에 요청 본문**을 붙여 보내고 있음
  - 일부 **로드 밸런서**는 본문을 버린다고 함
  - 일반적으로 좋은 생각은 아님. 일부 HTTP 구현에서는 아예 불가능함. 예를 들어 `fetch`가 그렇다  
    [https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/U...](<https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch>)  
    “GET 요청에는 본문을 포함할 수 없다”  
    투명 캐싱 때문에 이상한 문제가 생길 수도 있음

- 이제 **5자리 RFC 번호**까지 왔다는 게 놀라움

- 누군가 RFC 10000이 언제 발행될지 모호한 베팅을 걸었는데, 번호가 9998에서 곧장 10008로 넘어감. 아무도 이기지 못함  
  [https://manifold.markets/CollectedOverSpread/when-will-rfc-1...](<https://manifold.markets/CollectedOverSpread/when-will-rfc-10000-be-published>)

- HTTP 질의에서 검색 결과를 질의하려면 **QUERY 메서드**를 쓰고, 쿼리 매개변수는 추가하지 말라는 식이 됨  
  이름이 헷갈림. `query`라는 용어가 이미 HTTP 요청 일반을 가리키는 데 쓰이기 때문임  
  RFC 제목만 봐도 혼란스러웠음
  - `query`라는 용어가 HTTP 요청 일반을 가리키는 건 어떤 분야에서 그런가? 구어적으로 GET 요청을 질의라고 부를 때는 있지만, POST, PUT, DELETE에는 절대 그렇게 부르지 않음
  - 맞음. 게다가 꼭 질의일 필요도 없고 **멱등 효과**일 수도 있음. 차라리 IPOST, 즉 멱등 POST라고 부르는 편이 나았을 듯함  
    수정: 아, 캐시 가능성을 위해 QUERY를 부작용 없는 “안전한” 메서드로 선언했구나. 착각했음

- 이게 실제로 쿼리 문자열이 붙은 GET 요청을 야생에서 대체하게 된다면, 브라우저 북마크가 **요청 매개변수 보존**을 지원하길 정말 바람
  - 아마 그렇지는 않을 듯함. 현재 질의 용도로 POST를 쓰는 곳을 대체할 가능성이 큼

- 이 RFC의 범위 밖인 건 알지만, 이걸 쉽게 확장하면 JS `EventSource`가 **스트리밍 AI 질의**에도 동작하게 만들 수 있다는 점이 좋음  
  요청에 본문이 필요하다 보니 모두 POST를 쓰고, 스트리밍 결과는 응답에 `text/event-stream` 프로토콜을 자주 씀. 하지만 실제로 상태가 바뀌는 건 아니라 기술적으로는 잘 맞지 않고, `EventSource`는 고집스럽게도 GET만 쓸 수 있음. 그래서 많은 API가 자체 파서로 같은 기능을 다시 구현함

- `GET: Content (body) "no defined semantics"`를 보면, GET 메서드에 본문을 허용해도 나쁘지 않겠다고 생각했지만 원래 명세상 **GET 본문은 완전히 무시**되어야 함  
  또한 요청의 중요한 부분이 제거된 본문에 들어가면 캐싱도 깨질 수 있음
  - URI만 있는 GET은 리소스의 현재 표현을 가져온다는 의미론을 가짐. 이것이 하이퍼링크의 가장 기본 형태이고 웹이 동작하는 방식에 꽤 중요함  
    GET에 본문 매개변수를 추가하면, 같은 URI를 쓰는 두 요청을 같은 것을 가리킨다고 취급할 수 없게 되어 이 메서드의 제약을 깨뜨림
