RFC 10008: HTTP QUERY 메서드

개요

RFC 10008은 HTTP용 QUERY 메서드를 정의하여, 요청 본문이 필요한 서버 측 쿼리를 안전하고 멱등적으로 수행할 수 있는 표준화된 방법을 제공합니다. 이 메서드는 개발자들이 GET(안전하고 멱등하지만 URI 길이에 제한이 있음)과 POST(큰 본문을 지원하지만 본질적으로 안전하거나 멱등하지 않음) 사이에서 선택해야 했던 오래된 설계적 긴장을 해결합니다.

QUERY를 명시적으로 안전하고 멱등하도록 정의함으로써 IETF는 복잡한 쿼리에 대해 자동 재시도, 캐싱 및 조건부 요청 사용을 가능하게 하여, 이러한 쿼리가 POST 요청으로 강제되는 상황을 방지합니다.

QUERY 메서드의 핵심 의미론

안전하고 멱등적인 처리

QUERY 메서드는 안전하도록 설계되었습니다. 즉, 대상 리소스의 상태를 변경하거나 변경을 기대하지 않습니다. 또한 멱등하므로, 연결 실패 후 재시도하거나 요청을 반복해도 부분적인 상태 변화나 부작용이 발생하지 않습니다. 이는 일반적으로 상태 변화를 일으키는 POST와 구별됩니다.

요청 및 응답 구조

  • 요청 내용: GET과 달리 QUERY 요청은 본문(쿼리 내용)과 Content-Type 헤더를 필요로 합니다. 서버는 Content-Type이 없거나 내용과 일치하지 않을 경우 요청을 실패시켜야 합니다.
  • 성공 응답: 200 (OK) 응답은 쿼리가 성공적으로 처리되었으며, 결과가 응답 본문에 포함되어 있음을 나타냅니다.
  • 리소스 식별: 쿼리는 요청 본문으로 정의되지만, 대상 URI는 여전히 조회 대상 리소스를 식별합니다. URI의 쿼리 부분도 리소스를 추가로 식별하는 데 사용될 수 있습니다.

GET과 POST 연결하기

RFC 10008은 특정 응답 헤더를 사용해 QUERY 요청을 GET 요청으로 전환하는 공식 메커니즘을 제공합니다. 이를 통해 클라이언트는 쿼리 본문을 다시 전송할 필요 없이 이후 요청을 단순화할 수 있습니다.

동등 리소스

"동등 리소스"는 특정 QUERY 요청과 그 대상을 나타내는 가상 리소스입니다. 서버가 이 동등 리소스에 URI를 할당하면 2xx 응답의 Location 헤더에 반환될 수 있습니다. 클라이언트는 이후 해당 URI에 대해 GET 요청을 보내 본문을 재전송하지 않고도 동일한 쿼리를 반복할 수 있습니다.

결과 식별

서버는 Content-Location 헤더를 사용해 쿼리 작업의 특정 결과에 대한 URI를 제공할 수 있습니다. 이 URI는 일시적일 수 있으며, 클라이언트는 GET을 통해 결과를 다시 가져올 수 있습니다.

캐싱 및 조건부 요청

캐시 키 요구사항

QUERY 요청에 대한 응답은 캐시가 가능합니다. 그러나 쿼리가 URI가 아니라 본문으로 정의되기 때문에 캐시 키는 요청 내용 및 관련 메타데이터를 반드시 포함해야 합니다. 캐시는 효율성을 높이기 위해 의미적 정규화(예: 의미 없는 공백 제거)를 수행할 수 있으며, 클라이언트가 no-transform 지시자를 지정한 경우는 제외됩니다.

조건부 요청

QUERY는 표준 HTTP 조건부 헤더를 사용한 조건부 요청을 지원합니다. 클라이언트는 마지막 요청 이후 결과가 변경된 경우에만 반환하도록 요청할 수 있으며, 서버는 이를 만족하지 않을 때 304 (Not Modified) 응답으로 대역폭을 절약할 수 있습니다.

발견 및 협상

Accept-Query 헤더

QUERY 메서드 지원 및 허용되는 쿼리 형식을 알리기 위해 서버는 Accept-Query 응답 헤더를 사용할 수 있습니다. 이는 지원되는 미디어 범위(예: application/sql 또는 application/jsonpath)를 나열하는 구조화된 필드입니다.

메서드 발견

클라이언트는 OPTIONS 메서드를 사용해 Allow 헤더에 나열된 지원 메서드를 확인하거나, QUERY 요청을 시도하고 405 (Method Not Allowed) 응답을 처리함으로써 QUERY 지원 여부를 탐지할 수 있습니다.

보안 및 구현 고려사항

프라이버시와 로깅

쿼리에 민감한 정보가 포함된 경우, GET보다 QUERY를 사용하는 것이 바람직합니다. 요청 본문은 URI보다 중간자에 의해 로그에 남을 가능성이 낮기 때문입니다. 다만 RFC 10008은 Location이나 Content-Location을 통해 생성된 URI에 원본 요청 내용의 민감한 부분을 포함하지 말 것을 권고합니다.

CORS와 프리플라이트

QUERY는 CORS 안전 목록에 포함되지 않으므로, QUERY를 사용하는 모든 크로스 오리진 요청은 CORS 프리플라이트 요청이 필요합니다.

커뮤니티 관점

개발자들 사이의 논의는 새로운 HTTP 메서드 도입의 유용성과 잠재적 마찰을 모두 강조합니다:

  • AI 및 스트리밍에 대한 유용성: 일부 개발자는 QUERY가 본문이 필요한 스트리밍 AI 쿼리를 EventSource(오직 GET만 지원)와 함께 사용할 수 있게 해 프로토콜을 해킹하지 않아도 된다고 언급합니다.
  • 캐시 키에 대한 우려: 비평가들은 요청 본문을 캐시 키에 포함하는 것이 문제라고 지적합니다. 사용자 제어 본문이 트리비얼한 캐시 파괴 공격을 유발하거나, 복잡한 캐싱 로직이 보통 HTTP 계층 아래에서 이루어지기 때문입니다.
  • 채택 마찰: 모든 중간자와 클라이언트가 새로운 메서드를 지원하도록 하는 "배관" 작업이 기술적 장점에도 불구하고 광범위한 채택을 방해할 수 있다는 일반적인 우려가 있습니다.
  • 폼 통합: HTML 폼이 method="query"를 지원하도록 하여 POST 새로 고침 시 발생하는 "폼 재전송 확인" 경고를 없애자는 관심도 있습니다.

Sources