RFC 10008: HTTP QUERY メソッド

RFC 10008 は、HTTP における QUERY メソッドを定義しており、リクエストボディを必要とする安全でべき等なリクエストを実行するための標準化された方法を提供します。このメソッドは、GET(安全かつべき等ですが、通常は URI の長さに制限があります)と POST(リクエストボディをサポートしますが、デフォルトでは安全でもべき等でもありません)の間のギャップを埋めるものです。

問題点: URI の長さとメソッドのセマンティクス

従来、HTTP クライアントはクエリに GET を使用し、パラメータを URI クエリ文字列を介して渡してきました。しかし、クエリデータが URI に対してあまりに膨大になった場合、開発者はしばしば POST に頼ることになります。POST はリクエストボディをサポートしますが、自動再試行や中間者による効率的なキャッシュに必要な、安全かつべき等なセマンティクスを欠いています。

RFC 10008 は、QUERY を導入することでこの問題を解決します。これにより、クエリ操作への入力をリクエストのコンテンツとして渡すことができ、かつ明示的に安全でべき等な状態を維持できます。

QUERY メソッドの核となる特性

QUERY メソッドは、複雑なクエリのための GET の直接的な代替手段として設計されています。その主な特徴は以下の通りです:

  • 安全かつべき等: GET と同様に、QUERY リクエストは対象リソースの状態を変更せず、副作用なしに複数回繰り返すことができます。これにより、インフラストラクチャは接続失敗後の自動再試行を行うことができます。
  • リクエストボディ: GET とは異なり、QUERY はリクエストボディ(クエリ内容)と対応する Content-Type ヘッダーを期待します。サーバーは、Content-Type が欠落しているか、コンテンツと一致しない場合、リクエストを失敗させる必要があります。
  • キャッシュ可能: QUERY リクエストへのレスポンスはキャッシュ可能です。キャッシュキーには、リクエストのコンテンツと関連するメタデータを含める必要があります。効率を高めるために、キャッシュは、意味的に重要でない差異を排除するためにリクエストのコンテンツを正規化することがあります。

HTTP メソッドの比較

プロパティ GET QUERY POST
安全 はい はい 可能性がある (いいえ)
べき等 はい はい 可能性がある (いいえ)
リクエストボディ 定義されたセマンティクスなし 期待される 期待される
キャッシュ可能 はい はい はい (限定的)

リソースの識別とリダイレクト

重要なリソースは URI によって識別されるべきであるという原則を維持するために、RFC 10008 はサーバーがどのように QUERY リクエストを URI にマッピングできるかを説明しています:

  • 等価なリソース: サーバーは「等価なリソース」に URI を割り当てることができます。これは、特定の QUERY リクエストとそのターゲットを表すリソースです。割り当てられた場合、この URI は Location レスポンスヘッダーで提供され、クライアントは後続のリクエストで GET に切り替えることができます。
  • Content-Location: 成功したレスポンスには、操作の結果を保持するリソースを識別する Content-Location ヘッダーが含まれる場合があります。これは GET を介して取得できます。
  • リダイレクト: QUERY は標準的な HTTP リダイレクト(301, 302, 307, 308)をサポートします。303 (See Other) レスポンスは、元のクエリが Location ヘッダーの URI への GET リクエストによって達成できることを具体的に示します。

ディスカバリと実装

サーバーは、以下のメカニズムを使用して、QUERY メソッドのサポートと、受け入れるフォーマットを通知できます:

  • OPTIONS メソッド: クライアントは OPTIONS を使用して、QUERYAllow ヘッダーにリストされているかを確認できます。
  • Accept-Query ヘッダー: 新しい構造化フィールドである Accept-Query は、リソースがサポートする特定のクエリフォーマットのメディアタイプ(例: application/sql, application/jsonpath+json)をリストすることを可能にします。

セキュリティとパフォーマンスの考慮事項

セキュリティ

クエリパラメータに機密情報が含まれる場合、QUERYGET よりも好ましいです。これは、URI はリクエストボディよりも中間者によってログに記録される可能性が高いためです。ただし、結果のために一時的な URI を作成するサーバー(Location または Content-Location を介して)は、それらの URI が元のリクエストからの機密データを漏洩させないようにする必要があります。

CORS

QUERY は CORS のセーフリストに含まれるメソッドではないため、ブラウザベースのエージェントからのリクエストには CORS プリフライトリクエストが必要になります。

コミュニティの視点

RFC 10008 に関する開発者の議論では、セマンティクスの明確さを重視する層と、採用の普及と技術的なオーバーヘッドを懸念する層に分かれています:

"I love that this could easily be extended to make the JS EventSource to work on streaming AI queries... EventSource can only use GET for some obstinate reason."

"Including a strong motivating example might have helped sell this... it feels extremely odd to include the request body as part of the cache key."

"I can't help feel like momentum is going to be strongly against adoption."

"This makes me happy tbh, I was never a fan of creating POST /search エンドポイントを作成することに、堅牢な API を扱っているときには、あまり好きではありませんでした。"

Sources