CyberLibrarian

【注意】 このドキュメントは、W3CのWeb Annotation Protocol W3C Recommendation 23 February 2017の和訳です。
このドキュメントの正式版はW3Cのサイト上にある英語版であり、このドキュメントには翻訳に起因する誤りがありえます。誤訳、誤植などのご指摘は、訳者までお願い致します。

訳注: Annotation、Collection、Container等、頭文字が大文字になっている語句が本文中に多く出現しますが、それらは大文字・小文字を区別せずに訳しました。

First Update: 2017年3月11日


要約

アノテーションは、一般的に、資源または資源間の関連性に関する情報を伝えるために用いられます。簡単な例には、1つのウェブ・ページや画像に関するコメントやタグ、ニュース記事に関するブログの投稿が含まれます。

ウェブ・アノテーション・プロトコルは、ウェブ・アーキテクチャおよびRESTのベスト・プラクティスと一貫性のある方法でアノテーションを作成・管理するための転送メカニズムについて記述しています。

このドキュメントのステータス

この項は、このドキュメントの公開時のステータスについて記述しています。他のドキュメントがこのドキュメントに取って代わることがありえます。現行のW3Cの刊行物およびこの技術報告の最新の改訂版のリストは、http://www.w3.org/TR/のW3C技術報告インデックスにあります。

この勧告の公開により、W3Cは、この勧告で規定している機能は、アクティビティ・ストリームズ2.0[activitystreams-core]およびアクティビティ語彙[activitystreams-vocabulary]の仕様が勧告に進んだ際に、その変更によって影響を受けることはないと予想しています。

このドキュメントは、ウェブ・アノテーション・ワーキンググループによって勧告として発表されました。このドキュメントに関してコメントを行いたい場合には、public-annotation@w3.org(購読アーカイブ)にお送りください。どのようなコメントでも歓迎します。

ワーキンググループの実装報告書を参照してください。

このドキュメントは、W3Cメンバー、ソフトウェア開発者、他のW3Cグループ、および他の利害関係者によりレビューされ、W3C勧告として管理者の協賛を得ました。これは確定済みドキュメントであり、参考資料として用いたり、別のドキュメントで引用したりすることができます。勧告の作成におけるW3Cの役割は、仕様に注意を引き付け、広範囲な開発を促進することです。これによってウェブの機能性および相互運用性が増強されます。

このドキュメントは、2004年2月5日のW3C特許方針の下で活動しているグループによって作成されました。W3Cは、このグループの成果物に関連するあらゆる特許の開示の公開リストを維持し、このページには特許の開示に関する指示も含まれています。不可欠な請求権(Essential Claim(s))を含んでいると思われる特許に関して実際に知っている人は、W3C特許方針の6項に従って情報を開示しなければなりません。

このドキュメントは、2015年9月1日のW3Cプロセス・ドキュメントによって管理されています。

1. はじめに

この項は非規範的です。

システム間の相互運用性には、システム間でやり取りされるデータの構文とセマンティクス、そして、そのやり取りの転送メカニズムという、2つの基本的な側面があります。HTTPプロトコルとウェブ・アーキテクチャは、標準的なトランスポート層に関する重要な出発点となり、システム間でコンテンツを容易かつ効果的にやり取りするために使用できます。これらの基盤に基づくことにより、既存の技術やパターンを利用し、一貫性と開発容易性を確保することができます。

ウェブ・アノテーション・プロトコルは、アノテーションを作成、管理、検索するための転送メカニズムについて記述しています。この仕様のアノテーションは、ウェブ・アノテーション・データ・モデル[annotation-model]およびウェブ・アノテーション語彙[annotation-vocab]の要件に従っているものと想定されます。この仕様は、RESTの原則とリンクト・データ・プラットフォーム[ldp]の勧告を基にしており、それに精通していることが推奨されます。

1.1 プロトコルの目的

ウェブ・アノテーション・プロトコルの主な目的は、アノテーションのクライアントとサーバーがシームレスに相互運用できるような一連のインタラクションの標準を提供することです。アノテーションプロトコルのエンドポイントおよびそれとの対話方法を発見できることにより、クライアントを自動的に、または、ユーザが設定し、アノテーションを、一組のクライアントとサーバーに閉じ込めるのではなく、互換性のある遠隔システムに蓄積することができます。

1.2 概要

ウェブ・アノテーション・モデル、LDP、RESTに精通している人にとっては、アノテーション・プロトコルの大半は非常に明確でしょう。下記の側面が最も重要な新しい要件です。

1.3 適合性

非規範的と記している項と同じく、この仕様のすべての作成ガイドライン、図、例、注は、非規範的です。この仕様のその他の部分はすべて規範的です。

「することができる/してもよい(MAY)」、「しなければならない(MUST)」、「してはならない(MUST NOT)」、「推奨される(RECOMMENDED)」、「すべきである/する必要がある(SHOULD)」、「すべきでない/する必要がない(SHOULD NOT)」というキーワードは、[RFC2119]で記述されているように解釈されるべきです。

1.4 用語

IRI
IRI、すなわち国際化資源識別子は、URIがASCII文字のサブセットで構成されていなければならないのに対し、Unicodeの文字が認められているURI仕様の拡張です。IRIと、同等のエンコードされたURI形式との間には、変換のためのマッピング・アルゴリズムが存在しています。IRIは[rfc3987]で定義されています。
資源(Resource)
IRIで識別可能な(MAY)関心事項。
ウェブ・サーバー(Web Server)
HTTP応答を送信してHTTPリクエストにサービスを提供するために、接続を受け入れるプログラム。
アノテーション(Annotation)
ウェブ・アノテーション・データ・モデル[annotation-model]に従っているウェブ資源。
アノテーション・サーバー(Annotation Server)
このドキュメントで記述しているプロトコルによりアノテーションを利用し管理できるようにするウェブ・サーバー。
アノテーション・クライアント(Annotation Client)
このドキュメントで記述しているプロトコルによりアノテーションを検索し管理する目的でアノテーション・サーバーへの接続を確立するプログラム。
アノテーション・コンテナ(Annotation Container)
アノテーションの管理に用いるLDPコンテナ[ldp]。

2. ウェブ・アノテーション・プロトコルの原則

ウェブ・アノテーション・プロトコルは、次の基本原則を用いて定義されています。

3. アノテーション検索

アノテーション・サーバーは、アノテーションのIRIに次のHTTPメソッドをサポートしなければなりません(MUST)。

サーバーは、アノテーションの検索を含むすべてのインタラクションにHTTPではなくHTTPSを用いるべきです(SHOULD)。

サーバーは、ウェブ・アノテーション・プロファイルを用いてJSON-LD表現をサポートしなければなりません(MUST)。その応答には、application/ld+jsonというメディア・タイプのContent-Typeヘッダーがなければならず(MUST)、そのprofileパラメータにはhttp://www.w3.org/ns/anno.jsonldというウェブ・アノテーション・のプロファイルIRIがあるべきです(SHOULD)。

サーバーは、Turtle表現をサポートすべきで(SHOULD)、その他の形式をサポートできます(MAY)。複数のアノテーションの表現を利用できる場合は、サーバーは内容交渉をサポートすべきです(SHOULD)。様々なシリアル化に対する内容交渉は、希望するメディア・タイプをリクエストのHTTP Acceptヘッダーに含めることで実行されますが、クライアントは、サーバーがそのプレファレンスを尊重することを前提とすることはできません[rfc7231]。

サーバーは様々なJSON-LDプロファイルをサポートできます(MAY)。様々なJSON-LDプロファイルに対する内容交渉は、Acceptヘッダーの一部として、空白で区切られた引用符付きリストでJSON-LDメディア・タイプにprofileパラメータを追加することで実行されます。

サーバーは、アノテーションを検索するリクエストの処理中にエラーが発生しなかった時には、200のHTTPステータス・コードを用いるべきで(SHOULD)、3XXのHTTPステータス・コードを用いて新しいロケーションにリダイレクトできます(MAY)。

アノテーション・サーバーからの応答には、ターゲットIRIがhttp://www.w3.org/ns/ldp#Resourceで、relパラメータの値がtypeであるLinkヘッダー・エントリーがなければなりません(MUST)。http://www.w3.org/ns/oa#Annotationというアノテーション・タイプを同じrelタイプを用いて追加することもできます(MAY)。これは、たとえクライアントがその表現の形式を処理できなくても、検索された表現が資源とアノテーションであることをクライアントシステムに知らせるためのものです。

HEADおよびGETのリクエストでは、応答には、HTTP[rfc7232]のエンティティー・タグの概念を実装したエンティティー参照値を持つETagヘッダーがなければなりません(MUST)。この値は、更新または削除のリクエストを送信する時にクライアントが用いるでしょう。

応答には、アノテーションとのインタラクションに利用できるHTTPメソッド[rfc7231]を列挙したAllowヘッダーがなければなりません(MUST)。

HEADおよびGETのリクエストでは、サーバーが、形式またはJSON-LDプロファイルによる内容交渉をサポートしている場合、応答には、値にAcceptがあるVaryヘッダーがなければなりません(MUST)[rfc7231]。これは、そのリクエスト・ヘッダーの値に基づいて表現が変わるということをキャッシュが理解していることを確保するためです。

リクエスト:
例1
GET /annotations/anno1 HTTP/1.1
Host: example.org
Accept: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
応答:
例2
HTTP/1.1 200 OK
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Link: <http://www.w3.org/ns/ldp#Resource>; rel="type"
ETag: "_87e52ce126126"
Allow: PUT,GET,OPTIONS,HEAD,DELETE,PATCH
Vary: Accept
Content-Length: 287

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/annotations/anno1",
  "type": "Annotation",
  "created": "2015-01-31T12:03:45Z",
  "body": {
    "type": "TextualBody",
    "value": "I like this page!"
  },
  "target": "http://www.example.com/index.html"
}

4. アノテーション・コンテナ

アノテーション・サーバーが、作成、更新、削除の1つ以上を含むアノテーションの管理をサポートしている場合は、下記の項の要件が当てはまります。アノテーション・プロトコルは、ウェブ・アノテーション・データ・モデル[annotation-model]から派生した一部の追加の制約を用いた、リンクト・データ・プラットフォーム[ldp]仕様の利用法です。

アノテーション・サーバーは、アノテーション・コンテナという、アノテーションを管理できるコンテナを1つ以上提供しなければなりません(MUST)。アノテーション・コンテナは、コンテナ[ldp](アノテーションを管理するためのサービス)であると同時にOrderedCollection[activitystreams-core](アノテーションの順序付きリスト)でもあります。これには記述と技術情報を関連付けることができ、クライアントがそれをユーザに提供することで、そのユーザはそれを用いるべきか否かを判断できるようになります。コレクション・モデルのクラス、プロパティー、表現については、ウェブ・アノテーション・データ・モデルで記述されており、アクティビティ・ストリームズへのマッピングがウェブ・アノテーション語彙[annotation-vocab]で提供されています。

アノテーション・コンテナは、LDP基本コンテナ仕様を実装すべきですが(SHOULD)、ビジネス・ニーズを満たすために、直接コンテナや間接コンテナなどの他のタイプのコンテナを実装することもできます(MAY)。アノテーション・コンテナのURIには、クエリやフラグメント要素があってはならず(MUST NOT)、パス要素は「/」という文字で終了しなければなりません(MUST)。

実装は、アノテーション・コンテナとのすべてのインタラクションにHTTPではなくHTTPSを用いるべきです(SHOULD)。

アノテーション・コンテナの作成、管理、構造は、この仕様の範囲外です。追加情報については、リンクト・データ・プラットフォーム仕様[ldp]を参照してください。

4.1 コンテナ検索

アノテーション・サーバーは、アノテーション・コンテナのIRIで次のHTTPメソッドをサポートしなければなりません(MUST)。

アノテーション・コンテナにHTTP GETリクエストが行われた場合、サーバーはコンテナの記述を返さなければなりません(MUST)。その記述は、JSON-LDで利用できなければならず(MUST)、Turtleで利用できるべきで(SHOULD)、その他の形式で利用できてもかまいません(MAY)。コンテナの記述のJSON-LDシリアル化には、リクエストで別途定められている場合を除き、LDPコンテキスト(http://www.w3c.org/ns/ldp.jsonld)と、ウェブ・アノテーションのプロファイルとコンテキスト[annotation-model]の両方を用いるべきです(SHOULD)。

リクエストがエラーなく正常に完了し、クライアントのプレファレンスに基づくリダイレクションの必要がない場合には、サーバーは200のHTTPステータス・コードを用いるべきです(SHOULD)。

コンテナのIRIからの、GETHEAD、およびOPTIONSの応答のAllowヘッダーでは、アノテーション・コンテナとインタラクションを行うためにサポートしているすべてのメソッドが公言されているべきです(SHOULD)。Allowヘッダーは、他のどの応答にも含めることができます(MAY)。

アノテーション・コンテナは、次の要素を持つすべての応答においてLinkヘッダー[rfc5988]を返さなければなりません(MUST)。

HEADおよびGETのリクエストでは、アノテーション・コンテナからの応答には、HTTP[rfc7232]のエンティティー・タグの概念を実装したETagヘッダーが含まれていなければなりません(MUST)。この値は、アノテーションを更新しようとするクライアントと同じ方法でそれをIf-Matchリクエスト・ヘッダーに含めることで、コンテナを更新する時に管理クライアントが用いるべきです(SHOULD)。

GETリクエストにAcceptヘッダーがない場合、アノテーション・サーバーは、アノテーション・コンテナのJSON-LD表現で応答しなければなりませんが(MUST)、JSON-LDに対してプレファレンスを有するクライアントは、Acceptリクエスト・ヘッダーを用いてそれを明示的にリクエストすべきです(SHOULD)。

サーバーが、形式またはJSON-LDプロファイルによる内容交渉をサポートしている場合、アノテーション・コンテナからのHEADまたはGETリクエストへの応答には、リクエスト内のこのヘッダーの値に基づいて表現が変わるということをキャッシュが判断できるように、値にAcceptを含んだVaryヘッダーがなければなりません(MUST)。

アノテーションを作成するためにPOSTメソッドの使用をサポートしているアノテーション・コンテナからの応答には、GET、HEAD、およびOPTIONSリクエストに対する応答にAccept-Postヘッダーが含まれているべきです(SHOULD)。値は、クライアントがPOSTで送信するために受け入れ可能なコンマで区切りのメディア・タイプのリストです[ldp]。

例3: アノテーション・コンテナ・ヘッダーの例
Link: <http://www.w3.org/ns/ldp#BasicContainer>; rel="type"
Link: <http://www.w3.org/TR/annotation-protocol/>; rel="http://www.w3.org/ns/ldp#constrainedBy"
ETag: "0f6b5cd8dc1f754a1738a53b1da34f6b"
Vary: Accept
Allow: POST, GET, OPTIONS, HEAD
Accept-Post: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld", text/turtle

4.2 コンテナ表現

1つのコンテナ内に多くのアノテーションが存在している可能性が高いため、アノテーション・プロトコルは、コンテナの内容を返すためにActivityStreamsコレクションのページング・メカニズムを採用しています。個々のコレクション・ページには、すべてのページを横断した時に、クライアントがコンテナ/コレクションの完全な順序付きコンテンツを再構築できるような、管理されたアノテーションのサブセットを持つ順序付きリストが含まれています。個々のページに含まれるIRIやアノテーション記述の数はサーバー次第であり、ページ間で矛盾していてもかまいません。アノテーションをソートする機能は、応答では明示されません。

アノテーション・コレクションのJSON-LD表現に関する要件は、ウェブ・アノテーション・データ・モデルで定義されており、ここで要約しています。

コレクションは、それを識別するIRIを持っていなければならず(MUST)、少なくともAnnotationCollectionクラス(JSON-LDのコンテキストにおいてOrderedCollectionと関連付けられている名前)を持っていなければなりませんが(MUST)、利用するLDPコンテナのタイプを含むその他のタイプを持つこともできます(MAY)。それは、人間が読めるlabelを持っているべきで(SHOULD)、creatorcreatedなどのその他のプロパティーを持つことができます(MAY)。

コンテナに1つ以上のアノテーションがある場合、その表現には、firstプロパティーの値としてアノテーションの最初のページへのリンクが含まれているか、応答内に埋め込まれた最初のページの表現が含まれていなければなりません(MUST)。2ページ以上のアノテーションがある場合、表現には、lastプロパティーを用いて最後のページへのリンクがあるべきです(SHOULD)。

コンテナの表現には、コンテナ内のアノテーションの合計数を記述したtotalプロパティーが含まれているべきです(SHOULD)。コンテナには、コンテナ内のいずれかのアノテーションの最新のタイム・スタンプを記述したmodifiedプロパティーが含まれているべきです(SHOULD)。このタイム・スタンプにより、同じ数が追加・削除されて同じ数のアノテーションが存在している場合であっても、データを再キャッシュすべきタイミングをクライアントが検出できます。

応答で提供されるコンテナのIRIで、ページにIRIだけが含まれているのか、それともアノテーションの完全な記述が含まれているのかを区別できるべきです(SHOULD)。これは、クエリ・パラメータで行うことを推奨します(RECOMMENDED)。サーバーは、クライアントをこのIRIにリダイレクトし、そこに応答を配信することができます(MAY)。そうでない場合は、その値としてIRIを持つContent-Locationヘッダーが含まれていなければなりません(MUST)。

4.2.1 コンテナ表現のプレファレンス

サーバーの応答の表現を制御するコンテナ・リクエストには、次の3つのプレファレンスがあります。

  1. クライアントが、コンテナ記述のみを受け取り、コンテナ応答に埋め込まれているアノテーション(URIまたは完全な記述)は受け取りたくない場合、return=representation;include="http://www.w3.org/ns/ldp#PreferMinimalContainer"という値を持つPreferリクエスト・ヘッダーが含まれていなければなりません(MUST)。
  2. クライアントが、現在のコンテナ応答または将来のページ付き応答に埋め込まれているIRI参照のみとしてアノテーションを受け取りたい場合、return=representation;include="http://www.w3.org/ns/oa#PreferContainedIRIs"という値を持つPreferリクエスト・ヘッダーが含まれていなければなりません(MUST)。
  3. クライアントが、現在のコンテナ応答または将来のページ付き応答で完全なアノテーション記述を受け取りたい場合、return=representation;include="http://www.w3.org/ns/oa#PreferContainedDescriptions"という値を持つPreferリクエスト・ヘッダーが含まれていなければなりません(MUST)。

リンクト・データ・プラットフォーム[ldp]で定義されているとおり、クライアントは、複数のプレファレンスをincludeパラメータの値として送信できます(MAY)。しかし、サーバーが両方を同時に尊重することはできないため、クライアントは、同じリクエストにPreferContainedIRIsPreferContainedDescriptionsのプレファレンスの両方を含めてはなりません(MUST NOT)。PreferMinimalContainerプレファレンスが指定されている場合は、サーバーは、それにアノテーションや参照を埋め込むべきではなく(SHOULD NOT)、最初と最後のアノテーション・ページへの参照を含むべきです(SHOULD)。ページがIRI参照なのか、完全な記述なのかは、それぞれPreferContainedIRIsPreferContainedDescriptionsの使用で制御できます。クライアントがプレファレンスを指定していない場合は、サーバーは、PreferContainedDescriptionsの挙動をデフォルト設定とすべきです(SHOULD)。サーバーは、クライアントのプレファレンスを無視できます(MAY)。

4.2.2 アノテーションのない表現

クライアントが、アノテーション・コンテナの最小限の表現をリクエストした場合、応答にはldp:containsという述語を含むことも、応答内にアノテーションの最初のページを埋め込むこともしてはなりません(MUST NOT)

リンクされたページは、PreferContainedDescriptionsまたはPreferContainedIRIsプレファレンスに従うべきです(SHOULD)。

サーバーは、PreferMinimalContainerプレファレンスが提供されていなくても、アノテーションが埋め込まれていない表現を返すことができます(MAY)。

リクエスト:
例4: アノテーションのないコンテナ・リクエスト
GET /annotations/ HTTP/1.1
Host: example.org
Accept: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Prefer: return=representation;include="http://www.w3.org/ns/ldp#PreferMinimalContainer http://www.w3.org/ns/oa#PreferContainedIRIs"
応答:
例5: アノテーションのないコンテナ応答
HTTP/1.1 200 OK
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
ETag: "_87e52ce123123"
Link: <http://www.w3.org/ns/ldp#BasicContainer>; rel="type"
Link: <http://www.w3.org/TR/annotation-protocol/>; rel="http://www.w3.org/ns/ldp#constrainedBy"
Allow: POST,GET,OPTIONS,HEAD
Vary: Accept
Content-Length: 368

{
  "@context": [
    "http://www.w3.org/ns/anno.jsonld",
    "http://www.w3.org/ns/ldp.jsonld"
  ],
  "id": "http://example.org/annotations/?iris=1",
  "type": ["BasicContainer", "AnnotationCollection"],
  "total": 42023,
  "modified": "2016-07-20T12:00:00Z",
  "label": "A Container for Web Annotations",
  "first": "http://example.org/annotations/?iris=1&page=0",
  "last": "http://example.org/annotations/?iris=1&page=42"
}

4.2.3 アノテーションのIRIがある表現

サーバーがコンテナのプレファレンスをサポートしている場合、firstの値としてAnnotationPageを含み、そのitemsに、その含まれているアノテーションのIRIのみが含まれている応答でPreferContainedIRIsに応答しなければなりません(MUST)。

リンクされたページは、PreferContainedIRIsプレファレンスに従うべきです(SHOULD)。

PreferContainedIRIsPreferContainedDescriptionsのプレファレンスは互いに排他的です。

埋め込まれたIRIに対するリクエスト:
例6: コンテナ・リクエスト(埋め込まれたIRI)
GET /annotations/ HTTP/1.1
Host: example.org
Accept: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Prefer: return=representation;include="http://www.w3.org/ns/oa#PreferContainedIRIs"
応答:
例7: コンテナ応答(埋め込まれたIRI)
HTTP/1.1 200 OK
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Content-Location: http://example.org/annotations/?iris=1
ETag: "_87e52ce123123"
Link: <http://www.w3.org/ns/ldp#BasicContainer>; rel="type"
Link: <http://www.w3.org/TR/annotation-protocol/>; rel="http://www.w3.org/ns/ldp#constrainedBy"
Allow: POST,GET,OPTIONS,HEAD
Vary: Accept, Prefer
Content-Length: 397

{
  "@context": [
    "http://www.w3.org/ns/anno.jsonld",
    "http://www.w3.org/ns/ldp.jsonld"
  ],
  "id": "http://example.org/annotations/?iris=1",
  "type": ["BasicContainer", "AnnotationCollection"],
  "total": 42023,
  "modified": "2016-07-20T12:00:00Z",
  "label": "A Container for Web Annotations",
  "first": {
    "id": "http://example.org/annotations/?iris=1&page=0",
    "type": "AnnotationPage",
    "next": "http://example.org/annotations/?iris=1&page=1",
    "items": [
      "http://example.org/annotations/anno1",
      "http://example.org/annotations/anno2",
      "http://example.org/annotations/anno3",
      "http://example.org/annotations/anno4",
      "http://example.org/annotations/anno5",
      "http://example.org/annotations/anno6",
      ...
      "http://example.org/annotations/anno999",
    ]
  },
  "last": "http://example.org/annotations/?iris=1&page=42"
}

4.2.4 アノテーションの記述がある表現

サーバーがコンテナのプレファレンスをサポートしている場合、firstの値としてAnnotationPageを含み、そのitemsに完全なインラインのアノテーションが含まれている応答でPreferContainedDescriptionsに応答しなければなりません(MUST)。

リンクされたページは、PreferContainedDescriptionsプレファレンスに従うべきです(SHOULD)。

PreferContainedIRIsPreferContainedDescriptionsのプレファレンスは互いに排他的です。

埋め込まれた記述に対するリクエスト:
例8: コンテナ・リクエスト(埋め込まれた記述)
GET /annotations/ HTTP/1.1
Host: example.org
Accept: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Prefer: return=representation;include="http://www.w3.org/ns/oa#PreferContainedDescriptions"
例9: コンテナ応答(埋め込まれた記述)
HTTP/1.1 200 OK
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Allow: GET,OPTIONS,HEAD
Vary: Accept, Prefer
Content-Length: 924

{
  "@context": [
    "http://www.w3.org/ns/anno.jsonld",
    "http://www.w3.org/ns/ldp.jsonld"
  ],
  "id": "http://example.org/annotations/?iris=0",
  "type": ["BasicContainer", "AnnotationCollection"],
  "total": 42023,
  "modified": "2016-07-20T12:00:00Z",
  "label": "A Container for Web Annotations",
  "first": {
    "id": "http://example.org/annotations/?iris=0&page=0",
    "type": "AnnotationPage",
    "next": "http://example.org/annotations/?iris=0&page=1",
    "items": [
      {
        "id": "http://example.org/annotations/anno1",
        "type": "Annotation",
        "body": "http://example.net/body1",
        "target": "http://example.com/page1"
      },
      {
        "id": "http://example.org/annotations/anno2",
        "type": "Annotation",
        "body": {
          "type": "TextualBody",
          "value": "I like this!"
        },
        "target": "http://example.com/book1"
      },
      ...
      {
        "id": "http://example.org/annotations/anno50",
        "type": "Annotation",
        "body" : "http://example.org/texts/description1",
        "target": "http://example.com/images/image1"
      }
    ]
  },
  "last": "http://example.org/annotations/?iris=0&page=840"
}

4.3 アノテーション・ページ

個々のページは、アクティビティ・ストリームズのOrderedCollectionPageクラスのインスタンスであり、それは、ウェブ・アノテーションJSON-LDのコンテキストではAnnotationPageと呼ばれます。ページには、そのIRIまたは完全な記述のいずかを用いて、itemsプロパティーにアノテーションが含まれています。

アノテーション・コレクション・ページのJSON-LD表現に関する要件は、ウェブ・アノテーション・データ・モデルで定義されており、ここで要約しています。

アノテーション・ページは、それを識別するIRIを持っていなければならず(MUST)、少なくともAnnotationPageクラス持っていなければなりませんが(MUST)、その他のタイプを持つこともできます(MAY)。そのページが、コレクション内の最後のページでない場合は、nextプロパティーを用いて、それに後続するページへの参照がなければなりません(MUST)。そのページが、コレクション内の最初のページでない場合は、prevプロパティーを用いて、先行するページへの参照があるべきです(SHOULD)。ページは、0オリジン(zero-based)のstartIndexプロパティーを用いてコレクションの順序と相対的にitemsリスト内の最初のアノテーションの位置を示すべきです(SHOULD)。

各ページには、partOfプロパティーを用いて、その一部であるコレクションへのリンクがなければなりません(MUST)。コレクションの記述には、totalおよびmodifiedのプロパティーが含まれているべきです(SHOULD)。応答には、labelfirstlastのリンクなど、応答のコレクションのその他のプロパティーを含むことができます(MAY)。

クライアントは、ページをリクエストする時にPreferヘッダーを送信すべきではありません(SHOULD NOT)。これは、コレクションをリクエストする時にすでに考慮されているためです。

この仕様では、クライアントがページに、GET、HEAD、またはOPTIONS以外のリクエストを行う時に、特定の機能は必要ありません。

ページはLDPコンテナではないため、タイプを持つLinkヘッダーを含める必要はありません。コンテナのIRIに追加されたクエリ・パラメータでURLを構築できることは、実装上の便宜であり、資源のタイプを暗示するものではありません。

埋め込まれたIRIのインタラクションの例

リクエスト:
例10: ページ・リクエスト
GET /annotations/?iris=1&page=0 HTTP/1.1
Host: example.org
Accept: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
応答:
例11: ページ応答(埋め込まれたIRI)
HTTP/1.1 200 OK
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Allow: GET,OPTIONS,HEAD
Vary: Accept
Content-Length: 630

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/annotations/?iris=1&page=0",
  "type": "AnnotationPage",
  "partOf": {
    "id": "http://example.org/annotations/?iris=1",
    "total": 42023,
    "modified": "2016-07-20T12:00:00Z",
  },
  "startIndex": 0,
  "next": "http://example.org/annotations/?iris=1&page=1",
  "items": [
    "http://example.org/annotations/anno1",
    "http://example.org/annotations/anno2",
    "http://example.org/annotations/anno3",
    "http://example.org/annotations/anno4",
    "http://example.org/annotations/anno5",
    "http://example.org/annotations/anno6",
    ...
    "http://example.org/annotations/anno999",
  ]
}

埋め込まれた記述のインタラクションの例

リクエスト:
例12: ページ・リクエスト(埋め込まれた記述)
GET /annotations/?iris=0&page=0 HTTP/1.1
Host: example.org
Accept: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
例13: ページ応答(埋め込まれた記述)
HTTP/1.1 200 OK
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Allow: GET,OPTIONS,HEAD
Vary: Accept, Prefer
Content-Length: 924

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/annotations/?iris=0&page=0",
  "type": "AnnotationPage",
  "partOf": {
    "id": "http://example.org/annotations/?iris=0",
    "total": 42023,
    "modified": "2016-07-20T12:00:00Z",
  },
  "startIndex": 0,
  "next": "http://example.org/annotations/?iris=0&page=1",
  "items": [
    {
      "id": "http://example.org/annotations/anno1",
      "type": "Annotation",
      "body": "http://example.net/body1",
      "target": "http://example.com/page1"
    },
    {
      "id": "http://example.org/annotations/anno2",
      "type": "Annotation",
      "body": {
        "type": "TextualBody",
        "value": "I like this!"
      },
      "target": "http://example.com/book1"
    },
    ...
    {
      "id": "http://example.org/annotations/anno50",
      "type": "Annotation",
      "body" : "http://example.org/texts/description1",
      "target": "http://example.com/images/image1"
    }
  ]
}

4.4 アノテーション・コンテナの発見

アノテーション・コンテナのIRIは、あらゆるIRIでありえ(MAY)、すべてのウェブ・サーバーがその機能をサポートすることはありえないと思われるため、これらのサービスの可用性を発見できることは重要です。

資源上のアノテーションが参照先のコンテナ内で作成されるべきである(SHOULD)場合は、あらゆる資源をアノテーション・コンテナにリンクすることができます(MAY)。このリンクは、HTTP Linkヘッダーで伝送され、relパラメータの値はhttp://www.w3.org/ns/oa#annotationServiceでなければなりません(MUST)。

資源のHTML表現では、同等のlinkタグをドキュメントのヘッダーで用いることもできます(MAY)。

画像資源の例では、GETリクエストと、上記のアノテーション・コンテナへのリンクを持つ応答は、次のようになります。

リクエスト:
例14
GET /images/logo.jpg HTTP/1.1
Host: example.com
応答:
例15
HTTP/1.1 200 OK
Content-Type: image/jpeg
Link: <http://example.org/annotations/>; rel="http://www.w3.org/ns/oa#annotationService"
Allow: GET
Content-Length: 76983

[...]

5. アノテーションの作成、更新および削除

5.1 新しいアノテーションの作成

新しいアノテーションは、アノテーション・コンテナへのPOSTリクエストにより作成されます。JSON-LDとしてシリアル化されたアノテーションは、リクエストの本文で送信されます。アノテーションに関するすべての既知の情報が送信されるべきであり(SHOULD)、資源に関連付けられているIRIが既に存在している場合は、それを含めるべきです(SHOULD)。シリアル化にはウェブ・アノテーションJSON-LDプロファイルを用いるべきで(SHOULD)、サーバーは、別の方法で同じモデルが生成される場合であっても、他のコンテキストを拒否することができます(MAY)。サーバーは、ウェブ・アノテーション仕様[annotation-model]に従い、アノテーションとみなされないコンテンツを拒否できます(MAY)。

アノテーションを受け取った時に、サーバーは、アノテーションの任意の資源または空白ノードにIRIを割り当てることができ(MAY)、既に提供されていても、idプロパティーのアノテーション資源にIRIを割り当てなければなりません(MUST)。資源を個々に検索できる時には、サーバーはHTTPS IRIを用いるべきです(SHOULD)。アノテーションのIRIは、追加のコンポーネントを最後に追加したコンテナのIRIでなければなりません(MUST)。

サーバーは、アノテーションに情報を追加できます(MAY)。追加できる情報には、それを作成したエージェント、アノテーションの作成時間、構成資源の追加のタイプと形式が含まれます。

アノテーションにcanonicalプロパティーが含まれている場合は、その参照は変更せずに維持しなければなりません(MUST)。アノテーションのidプロパティーにIRIがある場合は、それをviaプロパティーにコピーすべきで(SHOULD)、アノテーションを利用できるサーバーが割り当てたIRIをidフィールドに入れて置き換えなければなりません(MUST)。

サーバーは、作成が成功した場合は201「生成」応答で、そうでない場合には、適切なエラーコードで応答しなければなりません(MUST)。応答には、アノテーションの新しいIRIを持つLocationヘッダーがなければなりません(MUST)。

リクエスト:
例16
POST /annotations/ HTTP/1.1
Host: example.org
Accept: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Content-Length: 202

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "type": "Annotation",
  "body": {
    "type": "TextualBody",
    "value": "I like this page!"
  },
  "target": "http://www.example.com/index.html"
}
応答:
例17
HTTP/1.1 201 CREATED
Allow: PUT,GET,OPTIONS,HEAD,DELETE,PATCH
Location: http://example.org/annotations/anno1
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Content-Length: 287
ETag: "_87e52ce126126"

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/annotations/anno1",
  "type": "Annotation",
  "created": "2015-01-31T12:03:45Z",
  "body": {
    "type": "TextualBody",
    "value": "I like this page!"
  },
  "target": "http://www.example.com/index.html"
}

5.2 アノテーションに対するIRIの提案

資源のコンテナのIRIに付加されるIRIパス・セグメントは、資源が作成された時に、リクエストのSlug HTTPヘッダーを用いて、アノテーション・クライアントにより提案できます(MAY)。サーバーは、それが既存の資源を識別していない限り、この名前を用いるべきですが(SHOULD)、それを無視し、自動的に割り当てた名前を用いることもできます(MAY)。

リクエスト:
例18
POST /annotations/ HTTP/1.1
Host: example.org
Accept: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Content-Length: 202
Slug: "my_first_annotation"

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "type": "Annotation",
  "body": {
    "type": "TextualBody",
    "value": "I like this page!"
  },
  "target": "http://www.example.com/index.html"
}
応答:
例19
HTTP/1.1 201 CREATED
Link: <http://www.w3.org/ns/ldp#BasicContainer>; rel="type"
Allow: PUT,GET,OPTIONS,HEAD,DELETE,PATCH
Location: http://example.org/annotations/my_first_annotation
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
ETag: "_87e52ce126126"
Vary: Accept
Content-Length: 301

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/annotations/my_first_annotation",
  "type": "Annotation",
  "created": "2015-01-31T12:03:45Z",
  "body": {
    "type": "TextualBody",
    "value": "I like this page!"
  },
  "target": "http://www.example.com/index.html"
}

5.3 既存のアノテーションの更新

アノテーションは、PUTリクエストを用いてアノテーションの全体の状態を置き換えることにより更新できます。アノテーション・サーバーはこのメソッドをサポートすべきです(SHOULD)。サーバーは、アノテーションの変更された部分のみを更新するために、PATCHリクエストの使用もサポートできますが(MAY)、その機能はこのドキュメントでは規定していません。

新しい状態へのアノテーションの置き換えは、PUTメソッドで行わなければならず(MUST)、その場合、リクエストの本文が、意図するアノテーションの新しい状態となります。クライアントは、複数のユーザが同じアノテーションを同時に修正することによる衝突を避けるために、編集プロセスが始まる前にサーバーから受信したETagの値を持つIf-Matchヘッダーを用いるべきです(SHOULD)。すべてのシステムに1つのアノテーションを変更する潜在力を持っているユーザが複数存在しているわけではなく、上書きが望ましい行為である状況をユースケースが規定している可能性があるため、この機能のサポートは必須ではありません。

サーバーは、canonicalviaのプロパティーの値が既に設定されている場合は、ビジネス・ロジックによってリクエストが以前のエラーとして厳然と正しく信頼できるようにならない限り、それらを修正する更新リクエストを拒否すべきです(SHOULD)。

成功した場合は、サーバーは、リクエストされたコンテンツ・タイプに応じて、アノテーションを本文として持つ200「OK」のステータスを返さなければなりません(MUST)。作成の場合と同様に、サーバーは、アノテーションの新しい状態を応答で返さなければなりません(MUST)。

リクエスト:
例20
PUT /annotations/anno1 HTTP/1.1
Host: example.org
Accept: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
Content-Length: 294
If-Match: "_87e52ce126126"

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/annotations/anno1",
  "type": "Annotation",
  "created": "2015-02-01T10:13:40Z",
  "body": {
    "type": "TextualBody",
    "value": "I REALLY like this page!"
  },
  "target": "http://www.example.com/index.html"
}
応答:
例21
HTTP/1.1 200 OK
Content-Type: application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"
ETag: "_87e52ce234234"
Link: <http://www.w3.org/ns/ldp#Resource>; rel="type"
Allow: PUT,GET,OPTIONS,HEAD,DELETE,PATCH
Vary: Accept
Content-Length: 331

{
  "@context": "http://www.w3.org/ns/anno.jsonld",
  "id": "http://example.org/annotations/anno1",
  "type": "Annotation",
  "created": "2015-02-01T10:13:40Z",
  "modified": "2015-02-02T20:43:19Z",
  "body": {
    "type": "TextualBody",
    "value": "I REALLY like this page!"
  },
  "target": "http://www.example.com/index.html"
}

5.4 既存のアノテーションの削除

クライアントは、DELETE HTTPメソッドを用いて、サーバーがアノテーションを削除するようにリクエストしなければなりません(MUST)。アノテーション・サーバーはこのメソッドをサポートしなければなりません(SHOULD)。クライアントは、If-MatchヘッダーでアノテーションのETagを送信して、それがアノテーションの最新バージョンに対する操作であることを保証すべきです(SHOULD)。

DELETEリクエストが正常に処理された場合は、サーバーは204のステータス応答を返さなければなりません(MUST)。削除されたアノテーションのIRIは、その後のアノテーションに再利用すべきではありません(SHOULD NOT)。削除されたアノテーションのIRIは、それが作成されたアノテーション・コンテナから削除しなければなりません(MUST)。応答の本文に関する要件はなく、空であってもかまいません(MAY)。

リクエスト:
例22
DELETE /annotations/anno1 HTTP/1.1
Host: example.org
If-Match: "_87e52ce126126"
応答:
例23
HTTP/1.1 204 NO CONTENT
Content-Length: 0

6. エラー条件

この項は非規範的です。

アノテーションを検索・管理する時に、エラーが発生することは避けられません。下記のHTTPステータス・コードの使用は、リクエストが失敗した理由を理解する方法をクライアントに提供します。発生する可能性がある一部の状況と、望ましいHTTPステータス・コードを下記に示します。このリストは、HTTPで既に確立されている以上の追加要件を課すものではなく、参考情報かつ説明的なものです。

コード 状況の例
400 アノテーション・クライアントは、リクエストが適切な仕様に従っていないためにアノテーション・サーバーが処理できないリクエストを送信した。
401 アノテーション・クライアントは、認証証明を提供しなかったため、アノテーションの作成や削除などのリクエストされた操作を実行する権限がない。
403 提供された認証証明がアノテーションまたはアノテーション・コンテナに対する特定のアクセス・コントロール方針の要件を満たさなかったため、アノテーション・クライアントは、リクエストされた操作を実行する権限がない。
404 リクエストされたアノテーションまたはアノテーション・コンテナは存在しない。
405 アノテーション・コンテナ・ページにPOSTを試みたり、その機能がサポートされていない時にアノテーションにPATCHを試みたりするなど、リクエストされたHTTPメソッドは、資源に対して許されていない。
406 例えば、クライアントがRDF/XMLをリクエストしたが、サーバーがその(オプションの)変換をサポートしていないなど、アノテーションまたはアノテーション・コンテナの表現に対するリクエストされた形式は利用できない。
409 アノテーション・クライアントは、アノテーション・コンテナの閉じ込めリストやサーバーの設定変更タイム・スタンプなどの、サーバーがクライアントに変更を許していない値を設定または変更しようとした。
410 アノテーションは過去に存在していたことが知られているが削除された。
412 アノテーション・クライアントは、変更されているアノテーションのETagと一致しないIf-Matchヘッダーを提供した。
415 アノテーション・クライアントは、アノテーションではないものや認識されないコンテキストなど、サーバーが処理できないエンティティー・ボディを送信した。

A. 勧告候補終了基準

この項は非規範的です。

この仕様を勧告案に進めるためには、下記の各機能の少なくとも2つの独立した実装がなければなりません。各機能は、異なる製品に実装でき、1つの製品がすべての機能を実装するという要件はありません。

機能

終了基準を評価する目的では、下記の操作を機能とみなします。

個々の機能は、HTTPヘッダー、ステータス・コード、エンティティー・ボディに関して、仕様で示されている要件に従って実装されなければなりません。特定の機能の有無によってその動作を変更しないソフトウェアは、勧告候補段階を終了する目的でその機能を実装しているとはみなされません。

B. 旧バージョンからの更新

この項は非規範的です。

B.1 2017年1月17日の勧告案からの更新

重要な変更はない。

B.2 2016年9月6日の勧告候補からの更新

2016年9月6日の勧告候補からのこの仕様の編集上の更新は、下記のとおりです。

B.3 2016年7月12日の勧告候補からの更新

2016年7月12日の勧告候補からのこの仕様の編集上の更新は、下記のとおりです。

B.4 2016年3月31日の草案からの更新

草案公開2016年3月31日草案公開からのこの仕様の重要な技術的変更点は、下記のとおりです。

C. 謝辞

ウェブ・アノテーション・ワーキンググループは、オープン・アノテーション・コミュニティ・グループの貢献に謝意を表します。コミュニティ・グループの成果が現在のデータ・モデルとプロトコルの基礎となりました。

この仕様の作成において、次の方々に、アイデア、フィードバック、レビュー、コンテンツ、批評およびインプットの提供でご協力いただきました。

Vladimir Alexiev、Art Barstow、Tim Berners-Lee、Chris Birk、Dan Brickley、Sarven Capadisli、Paolo Ciccarese、Tim Cole、Ray Denenberg、TB Dinesh、Sergiu Gordea、Benjamin Goering、Amy Guy、Ivan Herman、Frederick Hirsch、Antoine Isaac、Jacob Jett、Takeshi Kanai、Gregg Kellogg、Andreas Kuckartz、Randall Leeds、Hugo Manguinhas、Shane McCarron、Ben De Meester、Luc Moreau、Mark Nottingham、Addison Phillips、Davis Salisbury、Robert Sanderson、Felix Sasaki、Doug Schepers、Tzviya Siegman、Stian Soiland-Reyes、Manu Sporny、Nick Stenning、Jon Stroop、Lutz Suhrbier、Kyrce Swenson、Raphael Troncy、Simeon Warner、Erik Wilde、Dan Whaley、Benjamin Young

D. 参考文献

D.1 規範的な参考文献

[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[activitystreams-core]
Activity Streams 2.0. James Snell; Evan Prodromou. W3C. 15 December 2016. W3C Candidate Recommendation. URL: https://www.w3.org/TR/activitystreams-core/
[activitystreams-vocabulary]
Activity Vocabulary. James Snell; Evan Prodromou. W3C. 15 December 2016. W3C Candidate Recommendation. URL: https://www.w3.org/TR/activitystreams-vocabulary/
[annotation-model]
Web Annotation Data Model. Robert Sanderson; Paolo Ciccarese; Benjamin Young. W3C. W3C Recommendation. URL: https://www.w3.org/TR/annotation-model/
[annotation-vocab]
Web Annotation Vocabulary. Robert Sanderson; Paolo Ciccarese; Benjamin Young. W3C. W3C Recommendation. URL: https://www.w3.org/TR/annotation-vocab/
[cors]
Cross-Origin Resource Sharing. Anne van Kesteren. W3C. 16 January 2014. W3C Recommendation. URL: https://www.w3.org/TR/cors/
[ldp]
Linked Data Platform 1.0. Steve Speicher; John Arwe; Ashok Malhotra. W3C. 26 February 2015. W3C Recommendation. URL: https://www.w3.org/TR/ldp/
[rfc3987]
Internationalized Resource Identifiers (IRIs). M. Duerst; M. Suignard. IETF. January 2005. Proposed Standard. URL: https://tools.ietf.org/html/rfc3987
[rfc5988]
Web Linking. M. Nottingham. IETF. October 2010. Proposed Standard. URL: https://tools.ietf.org/html/rfc5988
[rfc7231]
Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content. R. Fielding, Ed.; J. Reschke, Ed.. IETF. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7231
[rfc7232]
Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests. R. Fielding, Ed.; J. Reschke, Ed.. IETF. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7232