12. Content Negotiation (コンテンツネゴシエーション)
ほとんどのHTTPレスポンスには、人間のユーザーによる解釈のための情報を含むエンティティが含まれています。当然、リクエストに対応する「最善の利用可能な」エンティティをユーザーに提供することが望ましいです。残念ながら、すべてのユーザーが何が「最善」であるかについて同じ好みを持っているわけではなく、すべてのユーザーエージェントがすべてのエンティティタイプを等しくレンダリングできるわけではありません。このため、HTTPは、複数の表現が利用可能な場合に、特定のレスポンスに対して最適な表現を選択するプロセスである、いくつかの「コンテンツネゴシエーション」(content negotiation) メカニズムを提供します。
注:これは「フォーマットネゴシエーション」(format negotiation) とは呼ばれません。代替表現は、同じメディアタイプであるが、そのタイプの異なる機能を使用したり、異なる言語を使用したりする可能性があるためです。
エンティティボディを含む任意のレスポンスは、エラーレスポンスを含めて、ネゴシエーションの対象となる場合があります (MAY)。
HTTPには、2種類のコンテンツネゴシエーションが存在する可能性があります:サーバー駆動ネゴシエーション (server-driven negotiation) とエージェント駆動ネゴシエーション (agent-driven negotiation)。これら2つのネゴシエーションは直交しているため、個別に使用することも組み合わせて使用することもできます。透明ネゴシエーション (transparent negotiation) と呼ばれる組み合わせアプローチは、キャッシュがオリジンサーバーによって提供されたエージェント駆動のネゴシエーション情報を使用して、後続のリクエストにサーバー駆動のネゴシエーションを提供する場合に発生します。
12.1 Server-driven Negotiation (サーバー駆動ネゴシエーション)
レスポンスの最適な表現の選択が、サーバーに配置されたアルゴリズムによって行われる場合、それはサーバー駆動ネゴシエーションと呼ばれます。選択は、レスポンスの利用可能な表現(それが変化する可能性のある次元、例えば、言語、コンテンツエンコーディングなど)と、リクエストメッセージ内の特定のヘッダフィールドの内容、またはリクエストに関連する他の情報(例えば、クライアントのネットワークアドレス)に基づいています。
利用可能な表現から選択するアルゴリズムをユーザーエージェントに説明することが困難な場合、またはサーバーが最初のレスポンスとともにクライアントに「最善の推測」を送信したい場合(「最善の推測」がユーザーにとって十分に良好である場合、後続のリクエストの往復遅延を回避したいと考える場合)、サーバー駆動ネゴシエーションが有利です。サーバーの推測を改善するために、ユーザーエージェントは、このようなレスポンスに対する好みを記述するリクエストヘッダフィールド(Accept、Accept-Language、Accept-Encodingなど)を含めることができます (MAY)。
サーバー駆動ネゴシエーションには以下の欠点があります:
-
サーバーは、特定のユーザーにとって何が「最善」であるかを正確に判断することは不可能です。これには、ユーザーエージェントの機能と特定のリクエストの意図された使用法を完全に理解する必要があるためです。
-
ユーザーエージェントが各リクエストに対してその機能を記述することは煩雑であり(利用可能な帯域幅を占有します)、重大なプライバシーリスク(ユーザーフィンガープリンティング)につながる可能性があります。
-
オリジンサーバーの実装が複雑になり、アルゴリズムの検証が困難になります。
-
サーバーアルゴリズムがユーザーエージェントの機能について仮定を行う場合、公開されている表現を制限する可能性があります。
HTTP/1.1には、サーバー駆動ネゴシエーションを有効にするための以下のリクエストヘッダフィールドが含まれています:Accept(セクション14.1)、Accept-Charset(セクション14.2)、Accept-Encoding(セクション14.3)、Accept-Language(セクション14.4)、およびUser-Agent(セクション14.43)。ただし、オリジンサーバーはこれらの次元に限定されず、リストされていないリクエストヘッダフィールドやリクエストに存在しない拡張ヘッダフィールドを含む、リクエストの任意の側面に基づいてレスポンスを変更できます (MAY)。
Varyヘッダフィールドは、表現を選択する際に使用されるパラメータを表現するために使用でき、これは、ユーザーエージェントがキャッシュの適用性を理解する際に役立つ可能性があります(セクション13.6を参照)し、Varyヘッダフィールドを生成するサーバーにも役立つ可能性があります(セクション14.44を参照)。
12.2 Agent-driven Negotiation (エージェント駆動ネゴシエーション)
エージェント駆動ネゴシエーションでは、初期レスポンスを受信した後、レスポンスの最適な表現の選択はユーザーエージェントによって実行されます。選択は、利用可能な表現のリスト(URIとその区別特性を含む)と、ユーザーまたはユーザーエージェントの好みに基づいています。
レスポンスが利用可能な表現の次元で変化する場合で、オリジンサーバーがリクエストを検査することによってユーザーエージェントにとって何が最善かを正確に判断できない場合、またはユーザーエージェントを構成することによってサーバー負荷とネットワーク使用を削減するために公開キャッシュが使用される場合、エージェント駆動ネゴシエーションが有利です。
エージェント駆動ネゴシエーションには以下の欠点があります:最適な代替表現を取得するために第2のリクエストが必要です。この第2のリクエストは、キャッシュが正しいレスポンスを提供できる場合(すでにキャッシュされている)、またはリソースのリストが小さい場合にのみ、知覚可能な遅延を追加します。さらに、この仕様はリストのための標準を提供せず、ユーザーエージェントが最良の選択を自動的に選択するための標準も定義していません。
HTTP/1.1では、エージェント駆動ネゴシエーションを実行する際にサーバーが使用する300 (Multiple Choices) および406 (Not Acceptable) ステータスコードを定義しています。
12.3 Transparent Negotiation (透明ネゴシエーション)
透明ネゴシエーションは、エージェント駆動ネゴシエーションとサーバー駆動ネゴシエーションの組み合わせです。キャッシュが、オリジンサーバーによって提供されたコンテンツネゴシエーション情報を使用して、ユーザーエージェントにサーバー駆動ネゴシエーションを提供する場合に使用されます。
透明ネゴシエーションの利点は、オリジンサーバーが利用できない場合に1回のリクエストの往復を削除することです。
透明ネゴシエーションの欠点は、コンテンツネゴシエーション情報が不完全または不正確な場合、誤った表現の選択につながる可能性があることです。
HTTP/1.1は、透明ネゴシエーションのためのヘッダを定義していません。