RFC 10008 HTTP QUERY メソッド 2026年6月
Reschke ほか 標準化過程 [ページ]
ストリーム:
インターネット技術タスクフォース (IETF)
RFC:
10008
カテゴリ:
標準化過程
公開:
ISSN:
2070-1721
著者:
J. Reschke
greenbytes
J.M. Snell
Cloudflare
M. Bishop
Akamai

RFC 10008

HTTP QUERY メソッド

概要

この仕様は、HTTP の QUERY メソッドを定義します。 QUERY は、リクエストターゲットに対して、含まれている 内容を安全かつ冪等な方法で処理し、その処理結果を 応答として返すよう要求します。これは POST リクエストに似ていますが、QUERY リクエストは 部分的な状態変更を懸念することなく、自動的に繰り返したり 再開したりできます。

このメモの位置付け

これはインターネット標準化過程の文書です。

この文書は、インターネット技術タスクフォース (IETF) による成果物です。IETF コミュニティの合意を表しています。この文書は 公開レビューを受け、公開について Internet Engineering Steering Group (IESG) の承認を得ています。インターネット標準に関する詳細な 情報は、RFC 7841 の第2節で確認できます。

この文書の現在の状態、正誤表、および フィードバックの提供方法に関する情報は、 https://www.rfc-editor.org/info/rfc10008 で確認できます。

目次

1. はじめに

この仕様は HTTP QUERY リクエストメソッドを、 ターゲットリソースがリクエストをどのように処理するかを記述した表現を含む、 安全かつ冪等なリクエスト(第 9.2 節、[HTTP])を 行うための手段として定義します。

一般的なクエリのパターンは次のとおりです。

GET /feed?q=foo&limit=10&sort=-published HTTP/1.1
Host: example.org

しかし、伝達するデータが大きすぎてリクエストの URI にエンコードできない場合、 このパターンには問題が生じます。

GET を使用する代わりに、多くの実装では、 以下の例に示すように HTTP POST メソッドを使用してクエリを実行します。 この場合、クエリ操作への入力は、 リクエスト URI のクエリコンポーネントを使用する代わりに、 リクエスト内容として渡されます。

クエリを要求するための HTTP POST の典型的な使用例は次のとおりです。

POST /feed HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded

q=foo&limit=10&sort=-published

しかし、この方式では、リクエストの送信先となるリソースとサーバーに関する 特別な知識がなければ、安全で冪等なクエリが実行されていることは 容易には分かりません。

QUERY メソッドは GET と POST の使用の間にある隔たりを埋める解決策を提供し、 上記の例は次のように表現できます。

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

q=foo&limit=10&sort=-published

POST と同様に、クエリ操作への入力はリクエスト URI の一部としてではなく、 リクエストの内容として渡されます。しかし POST とは異なり、このメソッドは明示的に安全かつ 冪等であり、キャッシュや自動再試行などの機能を動作させることができます。

重要なリソースはすべて URI によって識別されるべきであるという設計原則を踏まえ、 この仕様では、後で GET リクエストで使用できるように、サーバーが クエリ自体または特定のクエリ結果の両方に URI を割り当てる方法を説明します。

まとめると、次のようになります。

表 1: 関連するメソッドの プロパティの概要
GET QUERY POST
安全 はい はい いいえの場合がある
冪等 はい はい いいえの場合がある
クエリ自体の URI はい(定義上) 任意(Location 応答フィールド) いいえ
クエリ結果の URI 任意(Content-Location 応答フィールド) 任意(Content-Location 応答フィールド) 任意(Content-Location 応答フィールド)
キャッシュ可能 はい はい はい。ただし将来の GET または HEAD リクエストに対してのみ
内容(本体) 「定義されたセマンティクスなし」 想定される(セマンティクスはターゲットリソースによる) 想定される(セマンティクスはターゲットリソースによる)

1.1. 用語

この文書では、[第 3 節、[HTTP]で定義されている用語を使用します。

さらに、URI のクエリコンポーネント (第 4.2.2 節 、[HTTP])にあるパラメーターを URI クエリパラメーターと呼び、QUERY リクエストの リクエスト内容(第 6.4 節、 [HTTP])を クエリ内容と呼びます。

1.2. 表記規則

この文書におけるキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「NOT RECOMMENDED」、 「MAY」、および「OPTIONAL」は、 ここに示すようにすべて大文字で記述されている場合に限り、 BCP 14 [RFC2119] [RFC8174] に記載されたとおりに解釈されます。

2. QUERY メソッド

QUERY メソッドは、サーバー側のクエリを開始するために使用されます。 ターゲット URI によって識別されるリソースの 表現を要求する GET メソッド (第 7.1 節、[HTTP]で定義)とは異なり、QUERY メソッドは、ターゲットリソースに対して、そのターゲットリソースの範囲内で クエリ操作を実行するよう要求するために使用されます。

リクエストの内容とそのメディアタイプによってクエリが定義されます。 オリジンサーバーは、ターゲットリソースに基づいて操作の範囲を決定します。

Content-Type リクエストフィールド([HTTP]、第 8.3 節) が欠落している場合、またはリクエスト内容と一致しない場合、サーバーはリクエストを 失敗させなければなりません

すべての HTTP メソッドと同様に、ターゲット URI のクエリ部分は、 クエリ対象となるリソースの識別に関与します。それがクエリ結果に 直接影響するかどうか、およびどのように影響するかはリソース固有であり、 この仕様の範囲外です。

QUERY リクエストは、ターゲットリソースに関して安全です ([HTTP]、第 9.2.1 節)。 つまり、クライアントはターゲットリソースの状態を変更することを 要求も期待もしません。ただし、これはサーバーが、 追加情報を取得できる追加の HTTP リソースを作成することを 妨げるものではありません(第 2.3 節および 2.4 節を参照)。

さらに、QUERY リクエストは冪等です ([HTTP]、第 9.2.2 節)。 たとえば接続障害の後など、必要に応じて再試行または 繰り返すことができます。

第 15.3 節 、[HTTP]に従い、2xx(成功)応答コードは、 リクエストが正常に受信、理解、および受理されたことを示します。

特に、200(OK)応答は、クエリが正常に処理され、 その処理結果が応答内容として含まれていることを示します。

2.1. メディアタイプと コンテントネゴシエーション

QUERY リクエストのセマンティクスは、リクエスト内容と、 メディアタイプなどの関連メタデータの両方に依存します([HTTP]、第 8.3.1 節)。 一般に、内容とメタデータが一致しないリクエストに関する問題は、4xx(クライアントエラー)応答 ([HTTP]、第 15.5 節)で 拒否しなければなりません

以下の一覧では、さまざまな失敗ケースについて説明し、具体的なステータスコードを推奨します。

  • リクエストにメディアタイプ情報がない場合、そのリクエストは定義上不正であり、 400(クライアントエラー)などの 4xx ステータスコードで失敗する必要があります。
  • メディアタイプが指定されているもののリソースでサポートされていない場合、 415(サポートされていないメディアタイプ)が適切です。 これには特に、メディアタイプ自体は原則として既知であるものの、 ターゲットリソースに対する QUERY 固有のセマンティクスが存在しない場合も含まれます。 いずれの場合も、Accept-Query 応答フィールド(第 3 節)を使用して、 サポートされているメディアタイプをクライアントに通知できます。
  • メディアタイプが指定されているものの、実際のリクエスト内容と一致しない場合、 400(不正なリクエスト)を返すことができます。つまり、サーバーが リクエスト内容からメディアタイプを推測し、欠落している値または「誤った」値を 上書きすること(すなわち「コンテントスニッフィング」)は許可されていません。
  • メディアタイプが指定され、理解され、内容が実際にそのタイプと一致しているものの、 クエリの実際の内容のために処理できない場合、 ステータス 422(処理不能なコンテンツ)を使用できます。 たとえば、存在しないテーブルを指定する構文的には正しい SQL クエリが該当します。
  • クライアントが Accept フィールド ([HTTP]、第 12.5.1 節)を使用して、 リソースがサポートしていない特定の応答メディアタイプを要求した場合、 406(受理不能)ステータスコードが適切です。

2.2. 等価リソース

任意の QUERY リクエストに対する等価リソースとは、 GET リクエストに応答し、その QUERY リクエストとそのターゲットを表現し、 メッセージ内容とメタデータの両方を考慮するリソースです(第 6 節、[HTTP])。 特に、これにはコンテンツのメディアタイプなどの表現メタデータ (第 8 節、[HTTP]) が含まれます。

言い換えると、等価リソースは、QUERY を実装するリソースに リクエスト内容を組み込むことで導出されます。

等価リソースという用語は、選択された表現など、 HTTP の他の側面の動作を定義するために使用されます。サーバーはこれらのリソースに URI を割り当てることができますが、割り当てる必要はありません( 第 1.1 節、 [URI]を参照)。 割り当てた場合、これらのリソースは GET リクエストで アクセス可能になります。

2.3. Content-Location 応答フィールド

成功応答(2xx、第 15.3 節、[HTTP])には、 操作結果に対応するリソースの識別子を含む Content-Location ヘッダーフィールドを含めることができます。 詳細については、第 8.7 節、[HTTP] を参照してください。これは、クライアントが示された URI に GET リクエストを送信して、 直前に実行したクエリ操作の結果を取得できるというサーバーからの主張を表します。 示されたリソースは一時的な場合があります。

例については、付録 A.4.1 を 参照してください。

2.4. Location 応答 フィールド

サーバーは、QUERY リクエストの等価リソース(第 2.2 節)に URI を割り当てることができます。サーバーがそうする場合、そのリソースの URI を 2xx 応答の Location ヘッダーフィールドに含めることができます(第 10.2.2 節、[HTTP]を参照)。 これは、クエリ内容を再送信することなく、クライアントが 示された URI に GET リクエストを送信して、直前に実行したクエリ操作を 繰り返せるという主張を表します。このリソースの URI は 一時的な場合があります。将来のリクエストが失敗した場合、クライアントは 元の QUERY リクエストターゲットと以前に送信した内容を使用して再試行できます。

例については、付録 A.4.2 を参照してください。

2.5. リダイレクト

場合によっては、サーバーはユーザーエージェントを別の URI にリダイレクトすることで、 QUERY リクエストに間接的に応答することを選択できます( 第 15.4 節 、[HTTP]を参照)。

ステータスコード 301(恒久的に移動、[HTTP]、第 15.4.2 節)または 308(恒久的リダイレクト、[HTTP]、第 15.4.9 節) のいずれかを含む応答は、ターゲットリソースが Location 応答フィールド ([HTTP]、第 10.2.2 節)で参照される別の URI に恒久的に移動したことを示します。 同様に、ステータスコード 302(発見、[HTTP]、第 15.4.3 節)または 307(一時的リダイレクト、[HTTP]、第 15.4.8 節) のいずれかを含む応答は、ターゲットリソースが一時的に移動したことを示します。 4 つのすべての場合において、サーバーは、Location で参照される新しいターゲット URI に 同様の QUERY リクエストを送信することで、ユーザーエージェントが元の QUERY リクエストを 実行できることを示唆しています。

301 または 302 応答後に POST を GET リクエストとしてリダイレクトするための例外は、 QUERY リクエストには適用されないことに注意してください。

ステータスコード 303(See Other、第 15.4.4 節、[HTTP]) を含む QUERY への応答は、Location 応答フィールド ([HTTP]、第 10.2.2 節) で参照される URI に対する通常の取得リクエストを介して、 元のクエリを実行できることを示します。 HTTP の場合、これは 付録 A.4.3 の例に示すように、新しいターゲット URI に GET リクエストを送信することを意味します。

2.6. 条件付きリクエスト

QUERY リクエストの選択された表現(第 3.2 節、[HTTP])は、その QUERY リクエストの 等価リソース(第 2.2 節)に対する GET リクエストの場合と同じです。

条件付き QUERY は、選択された表現 (すなわち、コンテントネゴシエーション後のクエリ結果)を、 第 13 節、 [HTTP]で定義されている 条件付きヘッダーフィールドで記述された条件の下でのみ 応答に返すことを要求します。

例については、付録 A.5 を参照してください。

2.7. キャッシュ

QUERY メソッドへの応答はキャッシュ可能です。キャッシュは、第 4 節、[HTTP-CACHING]に従って、 後続の QUERY リクエストを満たすためにそれを使用してもかまいません

QUERY リクエストのキャッシュキー(第 2 節、[HTTP-CACHING])には、 リクエスト内容(第 6 節、[HTTP-CACHING])および関連する メタデータ(第 8 節、[HTTP])を 組み込まなければなりません

キャッシュ効率を向上させるために、キャッシュは最初にリクエスト内容と関連メタデータから、 意味的に重要でない差異を取り除いてもかまいません。たとえば次の方法があります。

  • コンテンツエンコーディングを削除する (第 8.4 節 、[HTTP])。
  • リクエストの Content-Type フィールドにある メディアサブタイプのサフィックス(例: 「+json」。第 4.2.8 節、[RFC6838]を参照) で示される形式規則に関する知識に基づいて正規化する。
  • リクエストの Content-Type フィールドで示される、 内容自体のセマンティクスに関する知識に基づいて正規化する。

このような変換はすべて、キャッシュキーを生成する目的でのみ実行され、 リクエスト自体を変更するものではないことに注意してください。

クライアントは、「no-transform」キャッシュディレクティブ(第 5.2.1.6 節、[HTTP-CACHING]) を使用して、このような変換を行わないことを望むと示すことができます (ただし、このディレクティブは助言的なものにすぎないことに注意してください)。

QUERY メソッドの応答をキャッシュすることは、本質的に GET への応答を キャッシュするより複雑です。キャッシュキーを決定するには、 リクエスト内容を完全に読み取る必要があるためです。QUERY 応答が 等価リソース(第 2.2 節)の URI を示す Location 応答フィールド(第 2.4 節)を提供する場合、 クライアントは後続のリクエストで GET に切り替えることができ、 それによって処理を簡略化できます。

2.8. 範囲リクエスト

QUERY の範囲リクエストのセマンティクスは、 第 14 節、[HTTP] で定義される GET のものと同一です。 ただし、バイト範囲リクエスト(執筆時点で定義されている唯一の範囲単位)は、 QUERY リクエストの結果にはほとんど価値がありません。

クエリ形式では、SQL の「FETCH FIRST ... ROWS ONLY」のように、 結果セットを制限したりページングしたりする独自の方法が定義されることがよくあります。 HTTP 範囲リクエストの代わりに、これらの組み込み機能が使用されることが想定されます。

3. Accept-Query ヘッダーフィールド

「Accept-Query」応答ヘッダーフィールドは、使用可能な 特定のクエリ形式のメディアタイプを識別しながら、 QUERY メソッドのサポートをリソースが直接通知するために使用できます。

Accept-Query には、パラメーターを除くメディア範囲値を含む Token または String のいずれかからなる List Structured Header Field を使用し、 「Structured Fields」構文 [STRUCTURED-FIELDS]で メディア範囲(第 12.5.1 節、 [HTTP])のリストを含みます。

メディアタイプのパラメーターがある場合、それらは String または Token 型の Structured Field Parameters にマッピングされます。 Token と String のどちらを選択するかは意味上重要ではありません。 つまり、受信者は Token を String に変換してもかまいませんが、 受信した型に基づいて異なる方法で処理してはなりません

メディアタイプは Token に完全にはマッピングされません。たとえば、 先頭に数字を使用できます。このような場合は String 形式を 使用する必要があります。

サポートされるワイルドカードの使用法は、任意のタイプに一致する「*/*」、 または示されたタイプの任意のサブタイプに一致する「xxxx/*」のみです。

フィールド値に列挙されたタイプの順序に意味はありません。

Accept-Query フィールドの値は、サーバー上で同じパスを共有するすべての URI に適用されます。 言い換えると、クエリコンポーネントは無視されます。同じリソースへのリクエストが 異なる Accept-Query 値を返した場合は、 第 4.2 節、[HTTP-CACHING]に従って、 最も最近受信した新鮮な値が使用されます。

例:

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

このフィールドの構文は、「Accept」(第 12.5.1 節、[HTTP]) などの他のフィールドと似ているように見えますが、 これは Structured Field であるため、 第 4 節、[STRUCTURED-FIELDS]で指定されているとおりに 処理しなければなりません

4. セキュリティ上の考慮事項

QUERY メソッドには、[HTTP]で説明されている すべての HTTP メソッドと同じ一般的なセキュリティ上の 考慮事項が適用されます。

URI(たとえばクエリコンポーネント)でリクエスト情報を 渡す代わりに使用できます。URI はリクエスト内容よりも 仲介者によってログに記録されたり、その他の方法で処理されたりする可能性が高いため、 場合によってはこちらが望ましいことがあります。別の場合には、クエリに 機密情報が含まれていると、URI がログに記録される可能性があることから、 GET より QUERY を使用する動機になることがあります。

サーバーが QUERY リクエストの結果を表現する一時的なリソースを作成し (たとえば Location または Content-Location フィールドで使用するため)、 そのリソースに URI を割り当て、リクエストにログへ記録できない機密情報が含まれている場合、 その URI は、元のリクエスト内容の機密部分を含まないように 選択すべきです

QUERY の内容を誤って正規化したり、 リソースが内容を処理する方法と大きく異なる方法で正規化したりするキャッシュは、 正規化によって偽陽性が生じた場合、誤った応答を返す可能性があります。

Cross-Origin Resource Sharing(CORS)を実装するユーザーエージェントからの QUERY リクエストには、 QUERY が CORS セーフリストメソッドの集合に含まれないため、 「プリフライト」リクエストが必要になります ([FETCH]を参照)。

5. IANA に関する考慮事項

5.1. QUERY メソッドの 登録

IANA は、QUERY メソッドを <http://www.iana.org/assignments/http-methods> の「Hypertext Transfer Protocol (HTTP) Method Registry」に追加しました (第 16.3.1 節、[HTTP]を参照)。

表 2: QUERY メソッドの定義
メソッド名 安全 冪等 仕様
QUERY はい はい RFC 10008 の 第 2 節

5.2. Accept-Query フィールドの登録

IANA は、Accept-Query フィールドを <https://www.iana.org/assignments/http-fields> の「Hypertext Transfer Protocol (HTTP) Field Name Registry」 に追加しました (第 16.1.1 節、[HTTP]を参照)。

表 3: Accept-Query フィールドの 定義
フィールド名 状態 構造化型 参照 コメント
Accept-Query 恒久 List RFC 10008 の 第 3 節

6. 参考文献

6.1. 規範的参考文献

[HTTP]
Fielding, R., 編, Nottingham, M., 編, および J. Reschke, 編, 「HTTP セマンティクス」, STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/info/rfc9110>.
[HTTP-CACHING]
Fielding, R., 編, Nottingham, M., 編, および J. Reschke, 編, 「HTTP キャッシュ」, STD 98, RFC 9111, DOI 10.17487/RFC9111, , <https://www.rfc-editor.org/info/rfc9111>.
[RFC2119]
Bradner, S., 「要件レベルを 示すために RFC で使用するキーワード」, BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC8174]
Leiba, B., 「RFC 2119 キーワードにおける大文字と 小文字の曖昧性」, BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[STRUCTURED-FIELDS]
Nottingham, M. および P. Kamp, 「HTTP の構造化フィールド値」, RFC 9651, DOI 10.17487/RFC9651, , <https://www.rfc-editor.org/info/rfc9651>.
[URI]
Berners-Lee, T., Fielding, R., および L. Masinter, 「Uniform Resource Identifier (URI): 汎用構文」, STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.

6.2. 参考情報

[FETCH]
WHATWG, 「FETCH」, WHATWG 現行標準, <https://fetch.spec.whatwg.org>. コミットスナップショット: <https://fetch.spec.whatwg.org/commit-snapshots/3bab31a55154bda73f25b45a23df718616f2f64e/>.
[RFC3253]
Clemm, G., Amsden, J., Ellison, T., Kaler, C., および J. Whitehead, 「WebDAV (Web Distributed Authoring and Versioning) のバージョニング拡張」, RFC 3253, DOI 10.17487/RFC3253, , <https://www.rfc-editor.org/info/rfc3253>.
[RFC4918]
Dusseault, L., 編, 「Web Distributed Authoring and Versioning (WebDAV) のための HTTP 拡張」, RFC 4918, DOI 10.17487/RFC4918, , <https://www.rfc-editor.org/info/rfc4918>.
[RFC5323]
Reschke, J., 編, Reddy, S., Davis, J., および A. Babich, 「Web Distributed Authoring and Versioning (WebDAV) SEARCH」, RFC 5323, DOI 10.17487/RFC5323, , <https://www.rfc-editor.org/info/rfc5323>.
[RFC6838]
Freed, N., Klensin, J., および T. Hansen, 「メディアタイプの仕様と 登録手順」, BCP 13, RFC 6838, DOI 10.17487/RFC6838, , <https://www.rfc-editor.org/info/rfc6838>.
[RFC8259]
Bray, T., 編, 「JavaScript Object Notation (JSON) データ交換形式」, STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC9535]
Gössner, S., 編, Normington, G., 編, および C. Bormann, 編, 「JSONPath: JSON のためのクエリ 式」, RFC 9535, DOI 10.17487/RFC9535, , <https://www.rfc-editor.org/info/rfc9535>.
[URL]
WHATWG, 「URL」, WHATWG 現行標準, <https://url.spec.whatwg.org>. コミットスナップショット: <https://url.spec.whatwg.org/commit-snapshots/52526653e848c5a56598c84aa4bc8ac9025fb66b/>.
[XSLT]
Kay, M., 編, 「XSL Transformations (XSLT) Version 3.0」, W3C 勧告, , <https://www.w3.org/TR/2017/REC-xslt-30-20170608/>. 最新版は https://www.w3.org/TR/xslt-30/ で入手できます。

付録 A.

以下の例は説明のみを目的としています。実際にこれほど短いクエリを 送信する必要がある場合は、GET を使用する方が適している可能性があります。

ほとんどの例で使用されるメディアタイプは「application/x-www-form-urlencoded」です (ブラウザーのユーザークライアントからの POST リクエストで使用され、 [URL]「application/x-www-form-urlencoded」 で定義されています)。 簡潔にするため Content-Length フィールドは省略されています。

A.1. 単純なクエリ

以下は直接応答を伴う単純なクエリです。

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

応答:

HTTP/1.1 200 OK
Content-Type: application/json

[
  { "surname": "Smith",
    "givenname": "John",
    "email": "smith@example.org" },
  { "surname": "Jones",
    "givenname": "Sally",
    "email": "sally.jones@example.com" },
  { "surname": "Dubois",
    "givenname": "Camille",
    "email": "camille.dubois@example.net" }
]

A.2. QUERY サポートの検出

QUERY のサポートを検出する簡単な方法として OPTIONS (第 9.3.7 節、[HTTP]) メソッドがあります。

OPTIONS /contacts HTTP/1.1
Host: example.org

応答:

HTTP/1.1 200 OK
Allow: GET, QUERY, OPTIONS, HEAD

Allow 応答フィールド(第 10.2.1 節、[HTTP])は、指定されたリソースで サポートされるメソッドの集合を示します。

OPTIONS を使用する以外の方法もあります。たとえば、サーバーがサポートしているかを 事前に知らなくても QUERY リクエストを試すことができます。その場合サーバーは リクエストを処理するか、Allow 応答フィールドを含む 405(メソッド不許可、 第 15.5.6 節、[HTTP]) などの 4xx ステータスで応答できます。

A.3. QUERY 形式の検出

QUERY でサポートされているメディアタイプは、 Accept-Query 応答フィールド(第 3 節) によって検出できます。

HEAD /contacts HTTP/1.1
Host: example.org

応答:

HTTP/1.1 200 OK
Content-Type: application/xhtml
Accept-Query: application/x-www-form-urlencoded, application/sql

どのリクエストメソッドへの応答に Accept-Query が含まれるかは、 アクセスされるリソースによって異なります。

Accept-Query を確認する代わりに QUERY リクエストを行い、 415 応答(サポートされていないメディアタイプ、第 15.5.16 節、[HTTP]) などの 4xx ステータスになった場合に、 Accept 応答フィールド(第 12.5.1 節、[HTTP]) を確認する方法もあります。

HTTP/1.1 415 Unsupported Media Type
Content-Type: application/xhtml
Accept: application/x-www-form-urlencoded, application/sql

A.4. Content-Location、 Location、および間接応答

2.3 節および 2.4 節で説明したように、 成功応答(2xx、第 15.3 節、[HTTP])の Content-Location および Location 応答フィールドは、 受信したリクエストの結果、または同じ操作を実行する将来のリクエストのいずれかについて、 GET リクエストに応答する代替リソースを識別する方法を提供します。 付録 A.1 の例に戻ると、次のようになります。

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

応答:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Location: /contacts/stored-results/17
Location: /contacts/stored-queries/42
Last-Modified: Sat, 25 Aug 2012 23:34:45 GMT
Date: Sun, 17 Nov 2024, 16:10:24 GMT

[
  { "surname": "Smith",
    "givenname": "John",
    "email": "smith@example.org" },
  { "surname": "Jones",
    "givenname": "Sally",
    "email": "sally.jones@example.com" },
  { "surname": "Dubois",
    "givenname": "Camille",
    "email": "camille.dubois@example.net" }
]

A.4.1. Content-Location の使用

上で受信した Content-Location 応答フィールドは、 それが含まれていた QUERY 応答の結果を保持するリソースを識別します。

GET /contacts/stored-results/17 HTTP/1.1
Host: example.org
Accept: application/json

応答:

HTTP/1.1 200 OK
Last-Modified: Sat, 25 Aug 2012 23:34:45 GMT
Date: Sun, 17 Nov 2024, 16:10:25 GMT

[
  { "surname": "Smith",
    "givenname": "John",
    "email": "smith@example.org" },
  { "surname": "Jones",
    "givenname": "Sally",
    "email": "sally.jones@example.com" },
  { "surname": "Dubois",
    "givenname": "Camille",
    "email": "camille.dubois@example.net" }
]

サーバーがこのリソースを無期限に実装し続ける保証はないため、 エラー応答の後、クライアントは新しい代替ロケーションを取得するために 元の QUERY リクエストを再実行する必要があることに注意してください。

A.4.2. Location の使用

Location 応答フィールドは、元の QUERY リクエストと同じ処理およびパラメーターに対する 現在の結果を GET への応答として返すリソースを識別します。

GET /contacts/stored-queries/42 HTTP/1.1
Host: example.org
Accept: application/json

この例では、Last-Modified フィールドで示されるように、 2024-11-17T16:12:01Z に 1 件のエントリーが削除されたため、 応答には 2 件のエントリーだけが含まれます。

HTTP/1.1 200 OK
Content-Type: application/json
Last-Modified: Sun, 17 November 2024, 16:12:01 GMT
ETag: "42-1"
Date: Sun, 17 Nov 2024, 16:13:17 GMT

[
  { "surname": "Smith",
    "givenname": "John",
    "email": "smith@example.org" },
  { "surname": "Dubois",
    "givenname": "Camille",
    "email": "camille.dubois@example.net" }
]

サーバーが引き続きリソースを公開しており、クエリ結果に変更がなかったと仮定すると、 次を含む後続の条件付き GET リクエストは、

If-None-Match: "42-1"

304(未変更)応答になります(第 15.4.5 節、[HTTP])。

A.4.3. 間接応答

サーバーは、ステータスコード 303(See Other、 第 15.4.4 節、[HTTP]) を使用して「間接」応答(第 2.5 節)を送信できます。

付録 A.4 の冒頭のリクエストに対して、 サーバーは次のように応答する場合があります。

HTTP/1.1 303 See Other
Content-Type: text/plain
Date: Sun, 17 Nov 2024, 16:13:17 GMT
Location: /contacts/stored-queries/42

See stored query at "/contacts/stored-queries/42".

これは直接応答に Location を含める場合と似ていますが、 クエリ結果は返されない点が異なります。これにより、サーバーは 代替リソースのみを生成または再利用できます。 このリソースはその後、 付録 A.4.2 に示すように使用できます。

A.5. 条件付きリクエスト

リクエストメディアタイプとして「application/sql」と 「application/xslt+xml」[XSLT]を サポートし、「text/csv」として応答を生成できる QUERY 実装リソースを考えます。 クエリ対象のデータセットには RFC 文書情報が含まれ、 クエリは年代別にグループ化された情報を返します。

QUERY /rfc-index.xml HTTP/1.1
Host: example.org
Date: Sun, 7 Sep 2025, 00:00:00 GMT
Content-Type: application/xslt+xml
Accept: text/csv

...Query content using XSLT...

応答:

HTTP/1.1 200 OK
Date: Sun, 7 Sep 2025, 00:00:00 GMT
Location: /stored-queries/4815162342
Content-Type: text/csv
Accept-Query: "application/sql", "application/xslt+xml"
Last-Modified: Sun, 31 Aug 2025, 08:44:00 GMT
Vary: Accept-Query, Content-Encoding, Content-Type

decade, total, with errata, % with errata, average page count
1960, 26, 5, 19.2, 5.3
1970, 666, 18, 2.7, 6.1
1980, 376, 44, 11.7, 23.4
1990, 1593, 269, 16.9, 25.5
2000, 2888, 1048, 36.3, 27.3
2010, 2954, 895, 30.3, 26.1
2020, 1133, 230, 20.3, 26.2

ここでは、サーバーが GET で後から使用するために、等価リソース (第 2.4 節)に パス「/stored-queries/4815162342」を割り当てています。

後でクライアントはクエリを繰り返しますが、 結果が変更された場合にのみ返すよう指定します。

QUERY /rfc-index.xml HTTP/1.1
Host: example.org
Date: Mon, 8, Sep 2025, 11:00:00 GMT
Content-Type: application/sql
Accept: text/csv
If-Modified-Since: Sun, 31 Aug 2025, 08:44:00 GMT
Vary: Accept-Query, Content-Type

...Same query, but using SQL...

クエリ対象のデータに変更がなかったため、サーバーは次のように応答します。

HTTP/1.1 304 Not Modified
Date: Mon, 8 Sep 2025, 11:00:00 GMT
Content-Type: text/csv
Location: /stored-queries/4815162342
Accept-Query: "application/sql", "application/xslt+xml"
Last-Modified: Sun, 31 Aug 2025, 08:44:00 GMT
Vary: Accept-Query, Content-Type

サーバーが等価リソースの URI を識別したため、そのリソースには GET でアクセスできます。特に、これによりクエリリクエストの 内容を再送信する必要がなくなります。

GET /stored-queries/4815162342 HTTP/1.1
Host: example.org
Date: Sun, 21, Sep 2025, 12:08:00 GMT
Accept: text/csv
If-Modified-Since: Sun, 31 Aug 2025, 00:00:00 GMT

ここではデータセットの状態が実際に変更されたため、新しい内容が返されます。

HTTP/1.1 200 OK
Date: Sun, 21, Sep 2025, 12:08:00 GMT
Content-Type: text/csv
Last-Modified: Thu, 18 Sep 2025, 19:56:00 GMT
Vary: Accept-Query, Content-Encoding, Content-Type

decade, total, with errata, % with errata, average page count
1960, 26, 5, 19.2, 5.3
1970, 666, 18, 2.7, 6.1
1980, 376, 44, 11.7, 23.4
1990, 1593, 269, 16.9, 25.5
2000, 2888, 1048, 36.3, 27.3
2010, 2954, 895, 30.3, 26.1
2020, 1133, 230, 20.3, 26.2

(この年代の行における変更に注意してください。)

以下の図は、条件付きリクエストの使用と、等価リソースに URI が割り当てられている場合 (およびクライアントがそれを利用している場合)にどのように異なるかを示しています。 架空のフィールド名「Validator」は説明目的で使用されています。

クライアント リソース 内容を含む QUERY 200 OK Validator: foo 内容を含む QUERY ('foo' を条件とする) 304 Not Modified Validator: foo 状態変更 内容を含む QUERY ('foo' を条件とする) 200 OK Validator: bar
図 1: QUERY のみを使用したデータフロー
クライアント リソース 内容を含む QUERY 等価リソース (/xyz を生成) 200 OK Validator: foo Location: /xyz GET ('foo' を条件とする) 304 Not Modified Validator: foo 状態変更 GET ('foo' を条件とする) 200 OK Validator: bar
図 2: GET で等価 リソースにアクセスするデータフロー

A.6. その他のクエリ形式

以下の例は、RFC の正誤表からなる JSON 形式の [RFC8259] データベースに対するリクエストを示します。

以下のリクエストは、eXtensible Stylesheet Language Transformations(XSLT)を使用して、 年および定義された正誤表の種類ごとにまとめられた 正誤表情報を抽出します。

QUERY /errata.json HTTP/1.1
Host: example.org
Content-Type: application/xslt+xml
Accept: application/xml, text/csv

<transform xmlns="http://www.w3.org/1999/XSL/Transform"
  xmlns:j="http://www.w3.org/2005/xpath-functions"
  version="3.0">

  <output method="text"/>

  <param name="input"/>

  <variable name="json"
    select="json-to-xml(unparsed-text($input))"/>

  <variable name="sc">errata_status_code</variable>
  <variable name="sd">submit_date</variable>

  <template match="/">
    <text>year, total, rejected, verified, hdu, reported</text>
    <text>&#10;</text>
    <variable name="en" select="$json//j:map"/>
    <for-each-group select="$en"
      group-by="substring-before(j:string[@key=$sd],'-')">
      <sort select="current-grouping-key()"/>
      <variable name="year" select="current-grouping-key()"/>
      <variable name="errata" select=
        "$en[$year=substring-before(j:string[@key=$sd],'-')]"/>
      <value-of select="concat(
        $year,
        ', ',
        count($errata),
        ', ',
        count($errata['Rejected'=j:string[@key=$sc]]),
        ', ',
        count($errata['Verified'=j:string[@key=$sc]]),
        ', ',
        count(
          $errata['Held for Document Update'=j:string[@key=$sc]]),
        ', ',
        count($errata['Reported'=j:string[@key=$sc]]),
        '&#10;')"/>
    </for-each-group>
  </template>

</transform>

応答:

HTTP/1.1 200 OK
Content-Type: text/csv
Accept-Query: "application/jsonpath", "application/xslt+xml"
Date: Wed, 19 Feb 2025, 17:10:01 GMT

year, total, rejected, verified, hdu, reported
2000, 14, 0, 14, 0, 0
2001, 72, 1, 70, 1, 0
2002, 124, 8, 104, 12, 0
2003, 63, 0, 61, 2, 0
2004, 89, 1, 83, 5, 0
2005, 156, 10, 96, 50, 0
2006, 444, 54, 176, 214, 0
2007, 429, 48, 188, 193, 0
2008, 423, 52, 165, 206, 0
2009, 331, 39, 148, 144, 0
2010, 538, 80, 232, 222, 4
2011, 367, 47, 170, 150, 0
2012, 348, 54, 149, 145, 0
2013, 341, 61, 169, 106, 5
2014, 342, 73, 180, 72, 17
2015, 343, 79, 145, 89, 30
2016, 295, 46, 122, 82, 45
2017, 303, 46, 120, 84, 53
2018, 350, 61, 118, 98, 73
2019, 335, 47, 131, 94, 63
2020, 387, 68, 117, 123, 79
2021, 321, 44, 148, 63, 66
2022, 358, 37, 198, 40, 83
2023, 262, 38, 121, 33, 70
2024, 322, 33, 125, 23, 141
9999, 1, 0, 0, 1, 0

別のクエリ形式である JSONPath [RFC9535] もサポートされていることを示す Accept-Query 応答フィールドに注意してください。 以下のリクエストは、2024 年以降に送信された拒否済みのすべての正誤表の 識別子を報告します。

QUERY /errata.json HTTP/1.1
Host: example.org
Content-Type: application/jsonpath
Accept: application/json

$..[
     ?@.errata_status_code=="Rejected"
     && @.submit_date>"2024"
   ]
   ["doc-id"]

応答:

HTTP/1.1 200 OK
Content-Type: application/json
Accept-Query: "application/jsonpath", "application/xslt+xml"
Date: Thu, 20 Feb 2025, 09:55:42 GMT
Last-Modified: Thu, 20 Feb 2025 06:10:01 GMT

[
  "RFC1185","RFC8407","RFC6350","RFC8467","RFC1157","RFC9543",
  "RFC9076","RFC7656","RFC2822","RFC9460","RFC2104","RFC6797",
  "RFC9499","RFC9557","RFC2131","RFC2328","RFC9001","RFC3325",
  "RFC9438","RFC2526","RFC2985","RFC7643","RFC9132","RFC6376",
  "RFC9110","RFC9460","RFC7748","RFC9497","RFC8463","RFC4035",
  "RFC7239","RFC9083","RFC9537","RFC9537","RFC9420","RFC9000",
  "RFC9656","RFC9110","RFC2324","RFC2549","RFC6797","RFC2549",
  "RFC8894"
]

付録 B. メソッド名 'QUERY' の選択

「Hypertext Transfer Protocol (HTTP) Method Registry」(<http://www.iana.org/assignments/http-methods>) には、「安全」かつ「冪等」というプロパティを持つ他の 3 つのメソッド、 「PROPFIND」[RFC4918]、 「REPORT」[RFC3253]、および 「SEARCH」[RFC5323]がすでに含まれています。

これらのいずれかを再利用し、この仕様で新しいメソッド「QUERY」として 定義しているものに一致するよう更新することも可能でした。実際、 この仕様の初期段階では「SEARCH」が使用されていました。

最終的にメソッド名「QUERY」が選択された理由は次のとおりです。

謝辞

アイデア、レビュー、フィードバックを提供してくださった HTTP Working Group のすべてのメンバーに感謝します。

特に以下の方々に感謝します。 Carsten BormannMark NottinghamMartin ThomsonMichael ThornburghRoberto PolliRoy Fielding、および Will Hawkins

貢献者

Ashok Malhotra は、この仕様につながる初期の議論に 参加しました。

Ashok Malhotra

この HTTP メソッドに関する議論は、2019 年の HTTP Workshop で Asbjørn Ulsberg によって再開されました。

Asbjørn Ulsberg

著者の連絡先

Julian Reschke
greenbytes GmbH
Hafenweg 16
48155 Münster
ドイツ
James M Snell
Cloudflare
Mike Bishop
Akamai