10 月 03 2008

Top / OpenSocial / Resultful Protocol

このページはOpenSocial Rrestful Protocolの翻訳です

概要

このAPIはクライアントがウェブページ上のガジェット外部にあるOpenSocialコンテナサーバーとやり取りするための、言語にもプラットフォームにも中立なプロトコルを定義します。プロトコルとしては、どんな言語でも、どんなプラットフォームでも比較的容易に実装可能なように作られています。この仕様は、ウェブページ上のガジェットから、ユーザーデータの同期を行うサーバーまで、様々なクライアントから利用することができます。

このプロトコルは主に、リソースとそのオペレーションについて扱い、HTTPプロトコル上でサーバーから取得や更新を行う標準のHTTPメソッド(GET、POST、PUT、DELETE等)を定義します。

データ表現がひとつだけでは全てのクライアントに対して理想的とは言えません。このプロトコルでは各リソースにつき、JSON RFC4627、XML、およびAtom/AtomPub RFC4287, RFC5023という3種類の表現方法を汎用的なマッピングルールに則って定義します。このマッピングルールにより、サーバーはプロトコルを3度実装することなく、1つのインターフェースを実装するだけで済ますことができます。

OpenSocialコンテナサーバーは拡張表現を定義して構いませんが、最低限ここで定義されているJSONとAtomをすべてのリソースについて、XMLをPeopleリソースについて実装する必要があります。XMLは、他のリソースについてもサポートする場合があります。

このプロトコルではActivity、Person、Group、AppDataリソースについて定義します。ほとんどの処理はこれらのリソースの取得(GET)、更新(PUT)、生成(POSTまたはPUT)、削除(DELETE)から成ります。また、ひとつのフィールドを更新するためだけに巨大なリソースを送信することなく、部分的に更新が可能なオプション機能を定義します。

OpenSocial API Backgroundでは下記で利用される背景となるコンセプトを解説しています。この文書ではOpenSocialに必要となる知識があることを前提としています。

データ表現

各リソースはJSON、XML、Atomの3つの表現形式を取ります。すべてのデータは各形式で表現可能でなければなりません。XML形式とJSON形式は1対1でマッピングされますが、Atom形式は各オブジェクトやコレクションについて別途定義します。このドキュメントでは、JSONおよびAtomについてのみ例を示します。XML形式についてはJSONから直接マッピングされ、12項のXSDの要件を満たさなければなりません。

各リソースは要素の階層ツリー構造で表現されます。親要素内の要素の順番は場面によって重要な場合と、そうでない場合があります。マッピングは内部的な階層とJSON/XML形式またはAtom形式から成ります。

各データ形式のフィールドで許可されているセットは11項(フィールド名)に記述されているセットと同一です。

Atom形式とJSON形式間の一般的なマッピングルールは下記の通りです。各データ形式には追加ルールが存在する場合があります。

  • Atom形式の全てのデータのデフォルトロケーションはatom:entry/atom:content/datatypeです。datatypeはルートノードで配信されるデータ型(<person>, <group>, <activity>, <appdata>)となります。
  • フィールド名はこのドキュメントの終わりでキャメルケース(例:'lastName')で指定されています。
  • 文字列はどちらの形式でも文字列として表現されます。
  • 日付とタイムスタンプはAtomPub(RFC3339)形式のdate-timeエレメントで表現されます。RFC4287の3.3章をご覧下さい。これらは"XSD Dates"としても知られています。誕生日のような年を除いた日付のみが必要とされる場合、年は0000と表現されなければなりません。
  • Enumは"display value"(ローカライズ、カスタマイズ可能な文字列)と"key"(キー)フィールドを持ったオブジェクトで表現されます。
  • 配列はJSONでは配列として表現され、XMLでは繰り返しフィールドとして表現されます。
  • サブオブジェクトはどちらの形式でもサブエレメントとして表現されます。
  • フィールドはJSON形式ではルートオブジェクトとして配置されます。Atom形式では、デフォルトではatom:content/datatype(例:personデータならatom:content/person)下に配置されます。ただし、フィールドによっては標準Atomフィールドに従い階層を上げ、atom:entry下にエイリアスされます。全てのデータ型で3つの標準エイリアスが存在します。
    • atom:entry/atom:idは"id"フィールドをエイリアスします。JSON形式のIDはOpenSocialでグローバルにユニークなIDです。これはコンテナのドメイン(example.org等)、コロン、およびその人物のコンテナのIDから成ります。コンテナのIDは英字(A-Za-z)、数字(0-9)、ドット(.)、ハイフン(-)およびアンダースコア(_)のみ含むことができます。例:example.org:78gh37261ddfdf。Atom形式ではOpenSocial ID文字列に"urn:guid:"を前置することで、必要なURIデータ型に変換されます。これらのルールはグローバルなユニークさを保ちつつもRESTful APIとJS APIのIDマッピングの一貫させます。
    • atom:entry/atom:updatedは最終更新日時(Activityの場合POSTED_TIME)または生成日時(他に適当な情報がない場合)のJSONフィールドをエイリアスします。
    • atom:entry/atom:publishedは生成日時(Activityの場合POSTED_TIME)のJSONフィールドをエイリアスします。

主なデータ型の例は下記に示します。各例では比較のため、実際のデータ(payload data highlighted)と、JSON, Atom両方の表現を示しています。

レスポンス

JSONまたはXML形式のリクエストに対する正常なレスポンスオブジェクトの構造は下記の通りです。ルート要素は、XML形式では明示的に示されるルート要素として、JSON形式では匿名ルートオブジェクトとしてresponseが返されます(JSONではresponseノードのオブジェクト値がレスポンスとして返されます)。responseノードは下記の子ノードを含む必要があり、サービスプロバイダによっては追加ノードを含む場合があります。startIndex、itemPerPage、totalResultsはOpenSearchに準拠していることに注意してください。

  • startIndex: startIndexを指定せずにリクエストして返される全結果のインデックス開始位置と比較して、このレスポンスで返される最初の結果のインデックス。一般的にはリクエストされたstartIndex値と一致するか、startIndexが指定されていない場合は0となります。
  • itemsPerPage: このレスポンスで返されるページごとの結果数。一般的にはクエリパラメータのcountに一致しますが、サービスプロバイダの制限を超える、または現在のstartIndexから返される結果がその数に満たない場合は、少ない結果数が返される場合があります。このフィールドはリクエストでcountが指定された場合のみ含まれなければならない。
  • totalResults: startIndexまたはcountが指定されていない場合に返されるコンタクト数の合計。この値は、現在使用されているページングに関わらず、リクエストのフィルタリングを反映した上で、どれだけの結果数を期待できるかをコンシューマに教えます。
  • entry: Section 7.2 (entry Element)で定義されている通り、リクエストに一致するアイテム一つ一つのオブジェクトの配列。パースの一貫性を保つため、結果が複数返される可能性がある場合(通常そうですが)は、0個や1個の場合でも、この値は常に結果の配列でなければなりません。リクエストがひとつのコンタクトのみを対象としている場合(例えばリクエストが/@me/@all/{id}や/@me/@selfといったAdditional Path Informationを含む場合)、entryはひとつのアイテムを含むオブジェクト("entry": [ { /* first item */ } ]または"entry": { /* only item */ })でなければなりません。

例:

application/json形式:

結果が一つの場合:

xml形式:

結果が一つの場合:

Atom形式の場合は、上記で述べたマッピングルールを使用し、XMLとは異なる基礎フォーマットを持ちます。

application/atom+xml形式:

Person

Personはひとりの人物についてのソーシャルネットワークにまつわる情報を持ちます。同じレコードがコンタクト/フレンド/プロフィールで利用されます。利用可能なフィールドと型については11項(Field Names)をご覧下さい。また、2項の一般的なマッピングルールもご覧下さい。

最低限のPerson例:

application/json形式:

application/xml形式:

application/atom+xml形式:

注意: atom:summary要素は、content要素内の構造化されたテキストまたはHTMLデータを表現する場所として適しています。atom:title要素はname.unstructuredのようにエントリの短い名前をコピーしてくる場所として適しています。サーバーはこれら、もしくは他のフィールドを追加することができ、汎用アグリゲータやツールに対してフィードを有効活用することができます。

Group

OpenSocial GroupはPeopleに所有され、友人や友人との関係をカテゴライズしたり、タグ付けしたりするため使用されます。RESTful APIではユーザーが利用しているグループを問い合わせ可能にしています。Groupはコレクションとして返され、各Groupは表示名および、そのPersonによって所有されるGroupないでユニークなID、URIリンクを持ちます。

Groupの例:

application/json形式:

application/xml形式:

application/atom+xml形式:

GroupはGroupコレクション中にのみ表示され、Personごとに利用可能なグループのリストを取得するために使用されます。

Activity

OpenSocial Activityはタイムスタンプ付きでイベントの記録や通知を表し、より詳細な情報へのポインタを持っています。

利用可能なフィールドと型については11項(Field Names)をご覧下さい。Activityは標準的なフィード処理コードとの互換性を最大限に保つため、広範囲なhoistingルールを持ちます。

  • atom:entry/atom:title は"title"をエイリアス
  • atom:entry/atom:summary は"body"をエイリアス
  • atom:entry/atom:link@rel="self" は"url"をエイリアス
  • atom:entry/atom:icon は"faviconUrl"をエイリアス
  • atom:entry/atom:source/atom:title は"streamTitle"をエイリアス
  • atom:entry/atom:source/atom:link@rel="self" は"streamUrl"をエイリアス
  • atom:entry/atom:generator/atom:uri は"appId"をエイリアス
  • atom:entry/atom:author/atom:uri は"userId"をエイリアス 最低限のActivity例:

application/json形式:

application/xml形式:

application/atom+xml形式:

注意: titleフィールドは<b>、<i>、<a>、<span>のHTMLタグのみを含むことができます。 コンテナはActivityを表示する際、この書式を無視することができます。

AppData

AppDataはアプリケーションによって保存されたkey/valueペアです。AppDataの標準的な単位は、ユーザーのためにアプリケーションが保存したkey/valueペアの全てです。ただし、APIは異なるタイプのクエリもサポートしています(詳細は下記)。フィールドのサブセットを取得するには、セレクタfields=を利用します(詳細は下記)。

独立したAppDataの例

最初の例はあるアプリケーションとユーザーのkey/valueペアの集合を表しています:

application/json形式:

application/xml形式:

application/atom+xml形式:

AppDataコレクションの例

この例では、クライアントが複数のユーザーをまたがるデータコレクションをリクエストした場合を表しています。結果はデフォルトでは、ユーザーをデータにマッピングする特別なJSON形式のコレクションになります。

application/json形式:
(XML形式は直接マッピング)

application/atom+xml形式:

各フィールドのデータはJSON形式が想定されており、そうでない場合は解釈されません。

オペレーション

OpenSocialでは標準のHTTPメソッドが使用されます。GETは取得、PUTは更新、POSTは新規作成、DELETEは破棄を行います。POSTは特殊で、コレクションを扱い、コレクション中に新しいActivityやPerson、AppDataを新規作成し、AtomPub仕様に従い、生成したリソースのベースURLをLocation: headerに返します。

PUTやDELETEが使えないといった制限されたクライアント、もしくは制限されたクライアントの向こう側にいるクライアントは、PUTまたはDELETEをX-HTTP-Method-Override:ヘッダを追加してPOSTに変換する必要があります。

   POST /... HTTP/1.1
   ...
   X-HTTP-Method-Override: PUT

サーバーはPOSTとX-HTTP-Method-Overrideを実際の処理が送信されてきたものとして扱わなければなりません。注意: OpenSocial0.8はクロスドメインのJSONP(コールバックを付加したGET)をサポートしませんが、サーバーによっては拡張としてサポートする場合があります。そういったサーバーでは適切なセキュリティと認証処理の実装が推奨されます。

リクエストの認証と認可のコンテキスト

各RESTfulのリクエストでは、通常認証/認可情報を必要とします。コンテキスト情報にはよく、リクエスト者のID(リクエストを発生させたユーザー)と、アプリケーションID(ユーザーのエージェントの役割を果たすアプリケーションかそれに類するもの)が含まれます。コンテナ特有の情報を含む場合もあります。

コンテナはOAuth Core 1.0のサービスプロバイダ(OAuthを介してアクセス可能なウェブアプリケーション)でなければなりません。コンテナはリクエストを確立するのに他の方法を提供することも可能です。また、コンテナはエンドユーザーが直接認証しないConsumer Request OAuth拡張をサポートしなければなりません。アプリケーションは明示的であれ、暗示的であれ、ユーザーが前もって処理に同意していることを保証しなければなりません。ただし、Consumer Request OAuthを利用するためには、コンテナが事前にアプリケーションによる信用の確立を必要としている場合があります。

コンシューマがユーザーIDを持ち、その特定のユーザー向けに処理を行うことを示したい場合は、OAuthの署名パラメータに、拡張としてxoauth_requestor_idパラメータを提示する必要があります。コンシューマは明示的であれ、暗示的であれ、ユーザーが事前にこの処理に同意した場合のみこれを提供しなければなりません。サービスプロバイダであるコンテナは、これらのパラメータを正当なものとして引き受ける、またはなかったものとして無視しなければなりません。

このようにリクエストは通常、リクエストを行うアプリケーション(OAuthコンシューマ)および、oauth_tokenで暗示的にか、xoauth_requestor_idで明示的にリクエストを行うユーザーが含まれます。また、拡張や他のチャネル(Cookie, URLパラメータ, クライアントSSL証明書等)を使って、さらなる追加情報が含まれる場合もあります。なお、コンテナは公開情報に対してのリクエストであれば、認証/認可情報を持たないリクエストを受け付ける場合があります。認可情報がないリクエストの場合は、(例えばプロフィールの)公開できる情報のみを提供する場合があります。

RESTful URLに提供されるデータは、リクエスト者やアプリケーションごとに変化することに注意してください。そのため、与えられたURIリソースの意味は「現在のリクエスト者/アプリケーションの組み合わせに対して許可された情報のビュー」となります。認証が行われず情報が提供できない場合は、HTTP 401 Unauthorizedレスポンスがクライアントに対して返されなければなりません。また、 情報の一部のみが返される場合は、200ステータスと共に、別の認可コンテキストならば追加情報があることを示す標準OAuth WWW-Authenticate:ヘッダを付加して返されなければなりません。

ディスカバリー

コンテナはサポートしているコレクションと機能を宣言し、ディスカバリドキュメントを使ってそれを発見するためのテンプレートを提供します。クライアントはコンテナのURL(example.org等)を起点にディスカバリプロセスを開始します。処理の完全な流れはhttp://xrds-simple.net/core/1.0/をご覧ください。要約すると:

クライアントが{container-url}に対してAccept: application/xrds+xmlヘッダを含んだGETリクエストを投げます。 コンテナはディスカバリドキュメントを指すX-XRDS-Location:ヘッダか、ドキュメントそのものを返します。 クライアントはX-XRDS-Location:ヘッダを受け取った場合、それに従いディスカバリドキュメントを取得します。 ディスカバリドキュメントはhttp://xrds-simple.net/core/1.0/で定義されている、OpenIDやOAuthディスカバリで利用されているのと同じフォーマットのXMLファイルです:

Serviceはコンテナが提供するそれぞれのサービスを告知します。各コンテナはサービスTypeをサポートしなければならず、他のものについてもサポートしている場合は、ディスカバリドキュメントに記述します。各ServiceはURI Template(1つの場合はURI)で定義されたリソースセットで構成されます。クライアントはURIを追跡し、必要なリソースで処理を行うためTemplateを展開します。(URI Templateの文法はhttp://www.ietf.org/internet-drafts/draft-gregorio-uritemplate-03.txtに文書化されています)

代理変数のセットは各サービスのTypeによって決まっています。主なサービスのTypeと代理変数の組み合わせは下記に記述します。OpenSocialへの拡張は、代理変数を文書化する必要があります。可読な文書の置き場は名前空間のURIが理想的であることに注意してください。

コアとなるOpenSocialサービスタイプ

この章ではすべてのOpenSocialコンテナがサポートしなければならないコアとなるType、そのXRDS形式と意味を定義します。特に指定されていない限り、すべてのHTTP処理はどのURIエンドポイントにも許可されています。許可されている処理を指定したいコンテナは、各リソースのHTTPヘッダにAllow:を提供する必要があります。

People

XRDS Type: http://ns.opensocial.org/2008/opensocial/people

guid
Peopleデータのオーナーを表す、コンテナを跨いでユニークなユーザーID、またはリクエスト者を表す@meグループで選択する(コレクション)場合は、ユーザー定義のローカルグループ名guidのPersonレコードを選択する場合は@self全てのコンタクトを選択する(コレクション)場合は@allコンタクトのサブセットである友達を選択する(コレクション)場合は@friendspid : コレクションを選択している場合、その中からひとりのPersonレコードを取り出す。pid値はコレクションに対して相対的な場合がある。

People URIの例:

/people/{guid}/@all        ユーザー{guid}と繋がりのある全てのPeopleのコレクション
/people/{guid}/@friends    ユーザー{guid}と繋がりのある全ての友達のコレクション(@allのサブセット)
/people/{guid}/{groupid}   ユーザー{guid}と繋がりがあり、グループ{groupid}に含まれる全てのPeopleのコレクション
/people/{guid}/@all/{pid}  ユーザー{guid}と繋がりのある特定の人の個別のPersonレコード。ユーザー{guid}の視点で見た情報{pid}
/people/{guid}/@self       ユーザー{guid}のプロフィールレコード
/people/@me/@self          リクエスト者のプロフィールレコード
/people/@supportedFields   JSON形式の場合は配列で、Atom形式の場合はリストで、コンテナがサポートするPeopleオブジェクトのすべてのフィールドを返す
/people/{guid}/@deleted    ユーザー{guid}と繋がりのあるPeopleのうち、削除されたものを全て返すオプションAPI。通常updateSinceパラメータと合わせて使用される。コンテナによっては下記のようなURI形式を使う場合があることに注意してください:
 /people.cgi?guid={guid}&groupid={groupid}

これはXRDSディスカバリ文書が、パラメータを具体的なURIにマッピングできるようクライアントに適切に与えられていれば、正式なURIパターンとなります。友達は適切なコレクション(例:/people/{guid}/@friends)にPOSTすることで追加することができます。コンテナは追加された友達をコレクションに追加する前に2つのオプトイン処理を必要とすることができ、この場合、リクエストが受け入れられ、最終的に成功するかどうかは別として202 Acceptedレスポンスを返さなければなりません。

Groups

XRDS Type: http://ns.opensocial.org/2008/opensocial/groups

guid
Peopleデータのオーナーを表すコンテナ上でユニークなユーザーID、またはリクエスト者を表す@me

Groups URIの例:

 /groups/{guid}           ユーザー{guid}に関連付けられたグループのコレクション

Activities

XRDS Type: http://ns.opensocial.org/opensocial/activities

guid
Activityデータのオーナーまたは受信者を表すコンテナ上でユニークなユーザーID、またはリクエスト者を表す@me
selector
下記のいずれか
  • グループ内のActivityを選択する(コレクション)場合、ユーザー定義のローカルグループ名
  • guidユーザーのActivityを選択する(コレクション)場合は@self
  • すべてのコンタクトを選択する(コレクション)場合は@all
  • 友達のActivityのみ選択する(コレクション)場合は@friends
appId
Activityを選択したいアプリケーションのID、または@appはリクエストを行っているアプリケーションを表す

Activity URIの例:

/activities/{guid}/@self               指定されたユーザーによって生成されたActivityのコレクション
/activities/{guid}/@self/{appid}       指定されたユーザーのためにアプリケーションが生成したActivityのコレクション
/activities/{guid}/@friends            指定されたユーザーの友達のActivityコレクション
/activities/{guid}/@friends/{appid}    指定されたユーザーの友達のためにアプリケーションが生成したActivityのコレクション
/activities/{guid}/{groupid}           指定されたユーザーの友達グループ{groupid}のActivityコレクション
/activities/{guid}/{groupid}/{appid}   指定されたユーザーの友達グループ{groupid}のためにアプリケーションが生成したActivityコレクション
/activities/{guid}/@self/{activityid}  個別のActivityリソース(通常コレクションから発見される)
/activities/@supportedFields           JSON形式の場合は配列で、Atom形式の場合はリストで、コンテナがサポートするActivityオブジェクトのすべてのフィールドを返す

AppData

XRDS-Type: http://ns.opensocial.org/2008/opensocial/appdata

guid
Peopleデータのオーナーを表すコンテナ上でユニークなユーザーID、またはリクエスト者を表す@me
selector
下記のいずれか
  • グループ内のAppDataを選択する(コレクション)場合、ユーザー定義のローカルグループ名
  • guidユーザーのみのAppDataを選択する(コレクション)場合は@self
  • すべてのコンタクトを選択する(コレクション)場合は@all
  • 友達のAppDataのみ選択する(コレクション)場合は@friends
appId
Activityを選択したいアプリケーションのID、または@appはリクエストを行っているアプリケーションを表す

AppData URIの例:

/appdata/{guid}/@self/{appid} ユーザー{guid}かつアプリ{appid}の全てのAppData
/appdata/{guid}/@friends/{appid} ユーザー{guid}の友達かつアプリ{appid}の全てのAppData(読み込みのみ)
/appdata/{guid}/@self/{appid}?fields=count ユーザー{guid}かつアプリ{appid}のcountフィールド

標準クエリパラメータ

これらのクエリパラメータは上記URLいずれでも利用することができる追加のqueryパラメータです。startIndexとcountパラメータはOpenSearch仕様に基づき解釈されます。

count={count} ページングされたコレクションのページサイズをリクエストする。指定されない場合、コンテナが返す数を決定することができる。ただし、コンテナはすべてのアイテムを返すことができるよう、大きなデフォルト値をサポートすべきである。 filterBy={fieldname} コレクションの場合、与えられたフィールドでフィルタされたエントリを返す filterOp={operation} "contains"をデフォルトとする、コレクションのフィルタリングに利用される操作。contains、equals、startsWith、presentが利用可能。 filterValue={value} コレクションをフィルタする際に利用される値。例えばfilterBy=name&filterOp=startsWith&filterValue=JohnはnameフィールドがJohnのすべてのアイテムを返す。Johnny、John Doeのいずれも含まれる。 format={format} 好みの形式(atom, jsonまたはxml)。デフォルトはjson fields={-join|,|field} 結果に含めたいフィールドのリスト。省略された場合の挙動はコンテナに依存する。ただし、最低限のフィールドセットは含まれなければならない。Peopleの場合はid、name、thumbnailUrlとなる。Activitiesの場合はidとtitleである。@allを指定することで全てのフィールドを返すよう指定することができる。 networkDistance={networkDistance} @friendsなどのグループ系リクエストを、友達を辿って{networkDistance}分先の人までのリクエストに変更します。コンテナによってはサポートされません。 sortBy={fieldname} コレクションで、与えられたフィールドでソートされたエントリを返します。 sortOrder={order} "ascending(昇順)"または"descending(降順)"で、昇順がデフォルト。コレクションのオブジェクトのソートに利用される。 startIndex={startIndex} ページコレクションのインデックス updatedSince={xsdDataTime} 指定されると、コンテナは更新日時が指定された値と同じかそれ以降のアイテムのみを返す。

注意: コンテナはコレクションからフィルターやソート、コレクションから最終更新アイテムセットを取得する全ての値をサポートする必要はありません。コンテナはフィルターやソート、updateSinceパラメータをサポートしない場合、結果に"filtered: false", "soreted: false", "updatedSince: false"を含めるべきです。

セキュリティの考慮

コンテナは慎重にセキュリティについて考えるべきです。コンテナはOAuthのサポートが必須ですが、コンシューマごと、ユーザーごとに許可される処理を決めるに当たり、適切なポリシーを用いるべきです。OAuthの仕様に従えば、コンテナはoauth_tokenを取得するためコンシューマがどのようにしてユーザーをコンテナウェブページに誘導するかを文書化しなければなりません。これはユーザーが信用情報を入力する必要があるため、フィッシングが行われる可能性があることに注意してください。

コンテナは、OAuth自体が暗号化やメッセージ本文の内容確認を行わないため、重要なデータにはSSL接続をサポートするべきです。コンテナは利用されているクライアントの種類に従ってセキュリティに関する判断を行うべきです。例えば一般的なデスクトップクライアントの場合、各クライアントごとにインストールされたConsumer Secretを保護する効果的な方法がありません。ただ、パートナーとなるサービスとのコミュニケーションにおけるセキュリティは、そのサービスのセキュリティに関する手順の効率とは別問題です。コンテナはリスクを軽減するため、未知のクライアントからのリクエスト数を制限したり、登録制にしたりする場合があります。コンテナはoauth_tokenをできるだけ狭くスコープするべきです(クライアントが読み込みのみ行う場合は書き込みさせないなど)。

同時処理制御(オプション)

この機能により、複数のコンテナが互いのデータを上書きしないよう、コンテナとクライアントの協力が可能になります。これはETag(詳しくはRFC5023の9.5章を参照)を利用した標準HTTP/AtomPubの楽観的同時処理メカニズム(optimistic concurrency mechanism)を利用します。PUTのボディについても、データ形式に関わらず同じメカニズムが適用されます。

ディスカバリ

同時処理制御はリソースごとに利用可能です。更新可能なリソースが同時処理制御をサポートする場合、コンテナはクライアントに情報を提供すると同時に、リソースの現在の状態をエンコードしたETagを提供すべきです。リソースが楽観的な同時処理をサポートしない場合は、更新リクエストに対して403 Not Implementedエラーと共に、If-Match:ヘッダを含む応答を返さなければなりません。楽観的な同時処理をサポートしないサーバーは、更新可能なリソースの応答時にETagを省略すべきです。クライアントはETagがなければ、楽観的同時処理が利用できないことを想定すべきです。

セマンティクス

クライアントはETagを与えられると、後続の更新のIf-Match:ヘッダにそのETagを提供することができます。このセマンティクスは、クライアントは新しい表現と前回のETagを提供するということです。(The semantics are that the client can supply the new representation and the previous ETag; )サーバーは現在のリソースの状態を確認し、クライアントが提供したETagと一致する場合(他の更新は挟まれなかったことを意味する)は更新、一致しない場合は409 Conflictエラーと共に新しいETagを返します。クライアントはこれを受けて、衝突を解消するための適切な処理を行うか、処理を終了することができます。クライアントは上書きによる問題を意識することなく、いつでもPUTで新しい状態を上書きすることもできます。部分更新がサポートされる場合(下記参照)、サーバーは基本となるリソース、または連続したPUTにより想定されるリソースへのETagを受け付けなければなりません。これは、ひとつのフィールドのみPUTしたい場合でも、GETでリソースの完全な表現を取得した際に受信したETagを与えることはルールに反しないことを意味します。ひとつのフィールドを上書きしたいだけの場合は、ETagを送りません。

部分更新

部分更新は、特にPeopleとAppDataに関して、完全なデータ更新内容を記述する必要がなくなります。主な用途としては、クライアントが完全なデータを取得した後、一部だけ更新したい場合が挙げられます。大抵の場合、クライアントは部分的な更新(例:たくさんのコンタクト情報のタグを変更する)をリソースのところどころに行ます。この部分更新を実現するためには、fieldsパラメータを利用します。

fieldsパラメータがurlで指定されると、そのフィールドのみがオブジェクトの更新時に参照されます。フィールドがパラメータリストに含まれるにもかかわらず、POSTの内容に含まれない場合、フィールドの削除と判断されます。フィールドがPOSTの内容に含まれるにもかかわらず、パラメータリストに含まれない場合、400 BAD Requestが返されます。フィールドがどちらにも含まれる場合、正常に更新が行われます。

メッセージング (オプション)

ソーシャルネットワークサービスによってはユーザー間で短いメッセージのやり取りを行うメカニズムを提供したい場合があります。この機能とポリシーはJS APIのrequestSendMessageと一致します。

ディスカバリ

コンテナはメッセージングをサポートする場合、ディスカバリドキュメントに"messages"Serviceを提示します。

セマンティクス

メッセージを作成しキューイングするには、クライアントはXRDSドキュメントでディスカバリすることのできる"outbox"コレクションリソースにメッセージをPUTします:

PUT /messages/{guid}/outbox/{msgid}

outboxは送信元ユーザーにより所有されます。outboxにメッセージを置くことで、ひとりまたは複数の受信者に対しての送信がリクエストされます。コンテナは自身のポリシー(セキュリティまたは負荷による制限)に従い、メッセージをフィルタまたは変更する自由が与えられています。メッセージのフォーマットはActivityと同様ですが、受信者のセット(osapi:recipient)が追加されます:

{msgid}はクライアントによって生成され、グローバルにユニークであるべきです。クライアントが失敗した場合を考慮していない場合、/messages/{source-uid}/outboxに対して標準のAtomPub POSTを使用し、IDの生成をコンテナに委ねることができます。どちらの場合でも成功した場合のレスポンスは201 Createdとなります。

サポートされていない場合、レスポンスコードは403 Not Implementedです。典型的には、コンテナはリクエスト者のIDと{guid}が一致するoutboxに対するPUTのみを許可しますが、これはコンテナのポリシーが決定する事項です。コンテナによってはスパムを防ぐため、友達同士などに制限する場合があります。

フィールド名

各フィールドは、コンタクトにつき最大1つのインスタンスしか存在しない単独フィールドか、複数存在しうる複数フィールドとして定義されます。特に指定されていない限り、すべてのフィールドはオプションであり、xs:string型です。

Person

各PersonはidとdisplayNameフィールドに何かしらの値を持って含まれなければなりません。他のフィールドはすべてオプションであり、すべてのサービスプロバイダがサポートされるフィールドすべてについてデータを提供できる訳ではないことを示しています。下記のフィールドリストは広範囲なため、サポートするサービスプロバイダは、標準的なフィールド名が利用可能です。

単独personフィールド

id
PersonのユニークなID。各Personのidは空ではない値を持たなければならない。このIDはこのユーザーのPeopleセット全体でユニークでなければならないが、複数ユーザーのデータ間でユニークである必要はない。また、他のリクエストでも、同じコンタクトが返される場合、同じIDでなければならない。例えばメールアドレスは同じ人物が将来異なるアドレスを利用する可能性があるため、IDには適さない。通常、"12345"のようなデータベース内部のIDが適当な選択肢である。
displayName
Personのエンドユーザーに表示するのに適した名前。各PersonのdisplayNameは空ではない値を持たなければならない。名前は分かっている場合は、そのPersonのフルネーム(例: Cassandra DollまたはMrs. Cassandra Lynn Dol, Esq.)であるべきであるが、利用可能なものが他にない場合は、ユーザー名やハンドル名(例: doll)でも構わない。与えられた値はエンドユーザーに対してサービスプロバイダがPersonを表示する際に主たる文字ラベルであるべきである。
name
11.1.3項(name要素)に記述されている通り、Personの本名の分解された構成要素と、完全にフォーマットされたバージョンである。
nickname
"Bob"や"Bobby"、"Robert"のように、現実生活でPersonを示すカジュアルな名前。このフィールドはユーザーのユーザー名(例: jsmarrやdaveman692)を示すために使われるべきではない。ユーザー名はpreferredUsernameフィールドで示されるべきである。
published
ユーザーのアドレス帳または友達リストにPersonが最初に追加された日付(このエントリの作成日)。この値はxs:dateTime(例: 2008-01-23T04:56:22Z)に準拠していなければならない。
updated
Personの詳細が更新された直近の日付(このエントリの更新日)。この値はxs:dateTime(例: 2008-01-23T04:56:22Z)に準拠していなければならない。最初の作成日以来一度も更新されていない場合、この値はpublishedと同じ値でなければならない。クエリパラメータのupdatedSinceはupdated値がこのxs:dateTimeと同じか、それより最近の人々を選択するために使用される。これによりコンシューマは、繰り返しユーザーデータにアクセスい、最後のアクセス時から新しく追加、または更新されたコンタクトのみをリクエストすることができる。
birthday
Personの誕生日。この値はxs:date(例: 1975-02-14)に準拠していなければならない。Personの年齢が秘匿され、年が利用できない場合、年の値は0000の場合がある。
anniversary
Personの結婚記念日。この値はxs:date(例: 1975-02-14)に準拠していなければならない。Personの年齢が秘匿され、年が利用できない場合、年の値は0000の場合がある。
gender
Personの性別。サービスプロバイダは下記いずれかの値を返すべきである: male, female, undisclosed。いずれにも含まれない場合は、異なる値が返される場合もある。
note
Personに関する意味や使い方を指定されていないメモ(通常ユーザーによるこのPersonのメモ)。このフィールドは新しい行を含む(MAY contain newlines)場合がある。
preferredUsername
Personのユーザー名を求めるサイト上でユーザーが決めたユーザー名(例: jsmarrやdaveman692)。このフィールドは、ユーザーのPersonよりもオーナーを表すのに有効かもしれない。例えばコンシューマによっては、この値を新しいサービスに登録する際の仮登録ユーザー名として使うことができる。
utcOffset
このレスポンスが返された時点での、Personの現在のタイムゾーンのUTCからの差分。値はxs:dateTimeの差分部分(例: -08:00)を満たさなければならない。この値は夏時間の際に変わる可能性があり、ユーザーのタイムゾーンからの差分の、現在値を示すだけのものである。
connected
ユーザーとこのPersonがサービスプロバイダの提供するサービスで相互に接続された関係かどうかを表すBoolean値。値はtrueかfalseでなければならない。下記relationshipフィールドが最低でも1つの値を持っている場合のみtrueでなければならないため、関係の中身に興味を持たないコンシューマにとっては、何かしらの相互に接続された関係が存在することを示すサマリー値と言える。伝統的なアドレス帳や、相互の同意を必要としない"フォロー"を利用するサービスの場合、この値は常にfalseとなる。

OpenSocial JavaScript APIの仕様に従い、下記の単独フィールドが追加定義されています: aboutMe, bodyType,currentLocation, drinker, ethnicity, fashion, happiestWhen, humor, livingArrangement, lookingFor, profileSong,profileVideo, relationshipStatus, religion, romance, scaredOf, sexualOrientation, smoker, status

複数personフィールド

特に指定されていない限り、すべての複数フィールドは標準的な3つのサブフィールドを持ちます:

value
メールアドレスや電話番号、URLのような、このフィールドの主たる値。複数フィールドにクエリパラメータでsortByが指定されている場合、デフォルトではこのvalueサブフィールドの値を元に並べ替えることを意味する。空ではない各複数フィールドは、最低限valueサブフィールドに値を持っているべきだが、他のサブフィールドについてはオプションである。
type
このインスタンスにおけるフィールドの型で、通常コンタクト情報の役割を示すために使用される。特に明記がなければ、この文字列値はwork, home, otherいずれかを示す。
primary
この複数フィールドのインスタンスが、優先される住所や、主なメールアドレスといった、主たる値、もしくは優先される値かを示すBoolean値。サービスプロバイダは同じ複数フィールドのインスタンスを2つ以上primary="true"としてはならないが、ひとつもマークが存在しないことも可能である。効率を考えた場合、サービスプロバイダはprimaryではないフィールドすべてのprimary="false"とすべきではなく、サブフィールド自体を省くべきである。
:数フィールドを返す際、サービスプロバイダは(メールアドレスやURL等)適していれば値を正規化すべきです。プロバイダは型が異なれば、同じ値を複数回返す事ができますが(例えばwork用とhome用で同じメールアドレスが使われるかもしれません)、コンシューマの処理が複雑になってしまうため、複数フィールドに対して同じ値の組み合わせを2回以上返すべきではありません。
emails
Personのメールアドレス。この値はjoseph@PLAXO.COMjoseph@plaxo.comとする等、サービスプロバイダによって正規化されるべきである。
urls
Personに関連するウェブページのURL。この値はJOSEPHSMARR.COM/about/をhttp://josephsmarr.com/aboutとする等、サービスプロバイダによって正規化されるべきである。typeの標準的な正規値に加え、このフィールドではblogとprofileという正規値が追加定義されている。
phoneNumbers
Personの電話番号。正規値は想定されていない。typeの標準的な正規値に加え、このフィールドではmobileとfax、pagerという正規値が追加定義されている。
ims
Personのインスタントメッセンジャーアドレス。どのメッセンジャーアドレスについても、公式の正規値ルールは存在しないが、サービスプロバイダはサービスに応じて全ての空文字を取り除き、アドレスを小文字かすべきである。typeの標準的な正規値に加え、このフィールドでは次のIMサービスを表す正規値を定義している: aim, gtalk, icq, xmpp,msn, skype, qq, and yahoo.
photos
Personの写真のURL。この値は正規化されたURLであるべきで、画像を含むウェブページではなく、実際の画像ファイル(例: GIF, JPEG, PNG)を指さなければならない。異なるサイズの画像を表す標準的な方法は存在しないが、サービスプロバイダは同じ画像を異なるサイズで返す場合がある。このフィールドはユーザーによって撮影された任意の写真を送信するために使用するべきでなく、コンタクトの表示用プロフィール写真に特化していることに注意すること。
tags
"お気に入り"や"web20"といった、Personに付けられたユーザー定義のカテゴリラベル。大文字/小文字は区別されるべきだが、同じ人物に大文字/小文字の違いだけの同じタグを複数付けるべきではない。このフィールドは文字列値からのみ成る。
relationships
サービスプロバイダによって双方向で示されるユーザーとPersonの関係タイプ。この値はXFNのrelationship値を満たすべきである(例: kin, friend, contact等)が、必要に応じて異なる値を使用しても構わない。このフィールドはtagsフィールドと並ぶカテゴリラベルだが、relationshipsは双方向に承認されている必要があるのに対し、tagsは互いの承認を必要としない。このフィールドは文字列値からのみ成る。
addresses
11.1.4項(address要素)に示されているPersonの住所。
organizations
11.1.5項(organization要素)に示されているPersonの現在または過去の組織属性。
accounts
11.1.6項(account要素)に示されているPersonのオンラインアカウント。

OpenSocialの仕様に従い、下記の複数フィールドが追加定義されています: activities, books, cars, children,food, heroes, interests, jobInterests, languages, languagesSpoken, movies, music, pets, politicalViews, quotes, sports,turnOffs, turnOns, tvShows

name要素

Personの本名の構成要素です。プロバイダはformattedサブフィールドにひとつの文字列としてフルネームを返すか、他のサブフィールドを使って各構成要素となるフィールドごとに返すか、または両方を選択する事ができます。両方が返された場合は、フォーマットされた名前は構成要素のフィールドを正しく組み合わせた同一の名前を記述しているべきです。

formatted
表示用に整形された、ミドルネームや肩書き、必要であれば敬称を含めたフルネーム(例: Mr. Joseph Robert Smarr, Esq.)。このフィールドのソートやフィルタに利用される主たるサブフィールド。
familyName
Personの家族名、もしくはほとんどの西欧言語で言う"姓"(例: フルネームMr. Joseph Robert Smarr, Esq.だとSmarr)。
givenName
Personの名前、もしくはほとんどの西欧言語で言う"名"(例: フルネームMr. Joseph Robert Smarr, Esq.だとJoseph)。
middleName
Personのミドルネーム(例: フルネームMr. Joseph Robert Smarr, EsqだとRobert)。
honorificPrefix
Personの前置敬称、もしくはほとんどの西欧言語で言う"肩書き"(例: フルネームMr. Joseph Robert Smarr, Esq.だとMr.)。
honorificSuffix
Personの後置敬称、もしくはほとんどの西欧言語で言う"サフィックス(Suffix)"(例: フルネームMr. Joseph Robert Smarr, Esq.だとEsq.)。

address要素

物理的住所の構成要素です。サービスプロバイダはformattedサブフィールドにひとつの文字列として完全な住所を返すか、他のサブフィールドを使って各構成要素となるフィールドごとに返すか、または両方を選択する事ができます。両方が返された場合は、フォーマットされた住所は構成要素のフィールドを正しく組み合わせた同一の住所を記述しているべきです。

formatted
表示用に整形された完全な住所。このフィールドは改行を含むことができる。このフィールドのソートやフィルタに利用される主たるサブフィールド。
streetAddress
部屋番号、道路名、私書箱、複数行に渡る住所(ストリートアドレス)を含む、住所のストリートアドレス部分。このフィールドは改行を含むことができる。
locality
住所の都市部分。
region
住所の州部分。
postalCode
住所の郵便番号部分。
country
住所の国名部分。

organization要素

このコンタクトの現在または過去の組織属性を記述します。単独の企業名と役職フィールドのみをサポートするサービスプロバイダの場合、nameプロパティとtitleプロバティを持ったひとつのorganization要素で表現すべきです。

name
組織名(例: 会社、学校、その他の組織)。返ってきた各組織名それぞれ空ではない値を持っているべきである。これがこのフィールドのソートやフィルタに利用される主たるサブフィールド。
department
組織の部署。
title
業務上の肩書きまたは組織内の役職。
type
jobとschoolを正規値とする組織型。
startDate
Personがこの組織に参加した日付。この値は可能な限り正当なxs:date値であること。ただし、フリーテキストで表現されると認識されているため、フォーマットされた文字列でなくても構わない。
endDate
Personがこの組織、もしくはtitleで指定された役職を辞めた日付。この値は可能な限り正当なxs:date値であること。ただし、フリーテキストで表現されると認識されているため、フォーマットされた文字列でなくても構わない。
location
この組織の物理的な場所。完全な住所か、"San Francisco"のような省略された場所。
description
この組織におけるPersonの役割のテキスト記述。このフィールドは改行を含む場合ができる。

account要素

このサービスプロバイダのサービス、または異なるサービス上の、Personが持つアカウントを示す。コンシューマはこのアカウントがサービスプロバイダによって実際にこのPersonに属することが確認されていると想定すべきではない。いずれのアカウントも、domainはこのアカウントの最も上位権限を持つドメイン(例: yahoo.com, reader.google.com)であり、空であってはならない。各アカウントはusernameかuseridのいずれかに空ではない値を持たなければならず、両方持つことも可能だが、同じアカウントでなければならない。これらのアカウントとは、あるサービスのユーザーが異なるサービスで同じ人物であることを知るために使用することができる。コンシューマがこれらのアカウントをプロフィールURLに変換したい場合、Social Graph Node Mapper (Fitzpatrick, B.)のようなオープンソースライブラリを使用することができる。

domain
"twitter.com"のような、このアカウントで最上位権限を持つドメイン。これはフィールドの主たるサブフィールであり、ソートやフィルタリングに利用される。
username
通常ユーザーが任意に選択する"jsmarr"のような英数字のユーザー名。
userid
"12345"や"1Z425A"といった、通常自動で割り振られ、番号のケースが多いが、英数字の場合もある、ユーザーID番号。

Activity

activity fields

OpenSocial javascript apiの仕様に従い、次のフィールドが定義されている: appId, body, bodyId, externalId, id, mediaItems, postedTime, priority, streamFaviconUrl, streamSourceUrl, streamTitle, streamUrl, templateParams, title, url, userId

Message

message fields

OpenSocial javascript apiの仕様に従い、次のフィールドが定義されている: body, bodyId, title, titleId, type

XML format XSD

リクエストに対するformat=xmlの応答は下記のXSDを満たさなければならない:

HTTPステータスコード

400 BAD REQUEST
OpenSocial application servers MUST return 400 BAD REQUEST under any one or more of the following conditions:
・Invalid request URI
・Invalid HTTP Header
・Receiving an unsupported, nonstandard parameter
・Receiving an invalid HTTP Message Body
401 UNAUTHORIZED
OpenSocial container servers MUST return 401 UNAUTHORIZED when receiving a request for a protected resource and the request is either
・Missing OAuth authorization credentials as described in OAuth Consumer Request 1.0, http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/1/spec.html.
・OAuth authorization credentials are present, but the user identity is not authorized to access the protected resource. If the request already included authorization credentials, the 401 response indicates that the request has been refused for those credentials. A 401 response MUST include a WWW-Authenticate header field indicating the request MAY present an OAuth token for the container server's realm. Example: WWW-Authenticate: OAuth realm="http://sp.example.com/"
403 FORBIDDEN
The server understood the request but is refusing to fulfill it. Authorization will not help. The current authorization context does not allow the request.
404 NOT FOUND
The server has not found a resource (such as a feed or entry) that matches the request URI.
405 METHOD NOT ALLOWED
The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource.
409 CONFLICT
The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required. Conflicts are most likely to occur in response to a PUT request. For example, this code can be used for a limit exceeded error as well as conflicting updates. See the error message for more information.
500 INTERNAL SERVER ERROR
Internal error. This is the default code that is used for all unrecognized errors.
501 NOT IMPLEMENTED
The request was valid but has not been implemented by the provider. A container SHOULD return 501 NOT IMPLEMENTED when receiving a request for an OPTIONAL/MAY feature that the container does not implement.