7.4. リソース

7.4.1. リソース

リソースは、RESTful Web サービスのデータソースです。各リソースタイプには、リソース表現 (通常 XML または JSON) を形成するために REST API が抽象化する共通のパラメーターセットが含まれています。ユーザーはリソース表現を表示して、パラメーターを編集し、API 内にあるリソースの URL にその表現を送り返して、リソースを変更することができます。またユーザーは、REST を介して個別のリソースを削除することもできます。
RESTful Web サービスは、リソースをコレクションにグループ化する作業も行います。ユーザーはコレクション内の全リソースの表現を表示することができます。またユーザーは、リソース表現を特定のコレクションに送信して、そのコレクション内に新たなリソースが作成することもできます。

7.4.2. リソースの取得

コレクション一覧から取得した URI に対して GET 要求を実行し、リソースのステータスを取得します。
Accept HTTP ヘッダーを追加して、応答形式の MIME タイプを定義します。
GET /api/[collection]/[resource_id] HTTP/1.1
Accept: [MIME type]
リソースからの追加情報は、All-Content: true ヘッダーを使用して取得することができます。RESTful Service Description Language (RSDL) により、どのリンクがこのヘッダーをサポートするかが記述されます。
GET /api/[collection]/[resource_id] HTTP/1.1
Accept: [MIME type]
All-Content: true

7.4.3. リソースの更新

前回のリソース URI GET 要求からの更新詳細を含む PUT 要求を実行して、リソースのプロパティーを変更します。変更可能なプロパティーに関する詳細は、各リソースタイプの説明を参照してください。
PUT 要求には、Content-Type ヘッダーが必要です。このヘッダーは、要求の一部として、本文コンテンツ内の表現の MIME タイプを API に通知します。
Accept HTTP ヘッダーを追加して、応答形式の MIME タイプを定義します。
PUT /api/collection/resource_id HTTP/1.1
Accept: [MIME type]
Content-Type: [MIME type]

[body]
これには、API ユーザーが変更を試みた、不変のリソースプロパティーは含まれません。完全に不変のリソースプロパティーの変更を試みると、API は応答本文内のエラーメッセージ表現で競合を報告します。
表現から省略されたプロパティーは無視されるため変更されません。

7.4.4. リソースの削除

URI に対して DELETE 要求を実行して、リソースを削除します。
Accept HTTP ヘッダーを追加して、応答形式の MIME タイプを定義します。
DELETE /api/[collection]/[resource_id] HTTP/1.1
Accept: [MIME type]
追加のプロパティーを指定するために、DELETE 要求内にオプションの本文コンテンツが必要な場合があります。オプションの本文コンテンツ付き DELETE 要求には、本文コンテンツ内の表現の MIME タイプを API に通知する Content-Type ヘッダーが必要です。DELETE 要求に本文コンテンツがない場合は Content-Type ヘッダーは省略します。

7.4.5. サブコレクションのリレーションシップ

サブコレクションのリレーションシップは、リソースとサブコレクション間の階層リンクを定義します。サブコレクションは、親リソースに関連して存在したり、意味を持ったりします。たとえば、仮想マシンに複数のネットワークインターフェースがある場合は、API は仮想マシンリソースとネットワークインターフェースのサブコレクション間のリレーションシップをマッピングすることになります。
サブコレクションは、次のリレーションシップタイプのモデリングに使用します。
  • 1 つの親リソースに複数の子リソースが含まれるようにしたり、1 つの子リソースが複数の親リソースに含まれるようにしたりすることが可能です。たとえば、仮想マシンには、複数のディスクを設定することができ、一部のディスクは複数の仮想マシンで共有されます。
  • マッピングされるリソースは、親リソースに依存します。親リソースなしでは依存するリソースは存在できません (例: 仮想マシンとスナップショット間のリンク)。
  • マッピングされるリソースは、親リソースからは独立して存在しますが、データはそのリレーションシップで関連付けられています (例: クラスターとネットワーク間のリンク)。
API は、link rel= 属性を使用して、リソースとサブコレクションとのリレーションシップを定義します。
GET /api/collection/resource_id HTTP/1.1
Accept: application/xml

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

<resource id="resource_id" href="/api/collection/resource_id">
    ...
    <link rel="subcollection"
      href="/api/collection/resource_id/subcollection"/>
    ...
</resource>
次に、サブコレクションに対してクエリーを実行します。
GET /api/collection/resource_id/subcollection HTTP/1.1
Accept: application/xml

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

<subcollection>
    <subresource id="subresource_id"
      href="/api/collection/resource_id/subcollection/subresource_id">
        ...
    </subresource>
    ...
</subcollection>

7.4.6. XML 要素のリレーションシップ

XML 要素のリンクは、リソース間のリレーションシップを表現するためのサブコレクションの代わりとして機能します。XML 要素のリンクは、単にリンク先の要素をポイントする「href」属性が記述した要素です。
XML 要素のリンクは、依存関係やリレーションシップに関連付けられたデータのないリソース間の単純な 1:N マッピングのモデリングに使用されます。(例: ホストとクラスター間のリレーションシップ)
このようなリレーションシップには、以下のような例があります。
  • サブコレクション内のリソースから親リソースへのバックリンク
  • 任意のリレーションシップがあるリソース間のリンク

例7.7 XML 要素を使用した、サブコレクションリソースからリソースへのバックリンク

GET /api/collection/resource_id/subcollection/subresource_id HTTP/1.1

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

<subcollection>
    <subresource id="subresource_id"
      href="/api/collection/resource_id/subcollection/subresource_id">
        <resource id="resource_id" href="/api/collection/resource_id"/>
        ...
    </subresource>
</subcollection>

7.4.7. アクション

大半のリソースには、標準の HTTP メソッドでは実現できない関数を提供するアクションリンクの一覧が含まれています。
<resource>
    ...
    <actions>
        <link rel="start" href="/api/collection/resource_id/start"/>
        <link rel="stop" href="/api/collection/resource_id/stop"/>
        ...
    </actions>
    ...
</resource>
API は、提供された URI に対して POST 要求を実行することによってアクションを呼び出します。POST の本文には、共通およびタスク固有のパラメーターをカプセル化した action 表現が必要です。

表7.6 共通のアクションパラメーター

要素説明
asyncサーバーが 202 Accepted で即時に応答し、完了確認のポーリングのための href リンクがアクション表現に記載されている場合は true に指定します。
grace_period猶予期間 (ミリ秒単位)。アクション開始前に満了する必要があります。
個々のアクションおよびそれらのパラメーターについては、各リソースタイプの説明を参照してください。 特定のアクションには必須のパラメーターがあり、それらが指定されていない場合には fault 応答で示されます。
POST 要求には本文コンテンツに XML 表現が必要なため、アクションにも Content-Type: application/xml ヘッダーが必要です。
アクションが非同期で開始されると、202 Accepted の即時応答によりタスクのステータスをモニタリングするためのリンクが提供されます。
POST /api/collection/resource_id/action HTTP/1.1
Content-Type: application/xml
Accept: application/xml

<action>
    <async>true</async>
</action>

HTTP/1.1 202 Accepted
Content-Type: application/xml

<action id="action_id"
  href="/api/collection/resource_id/action/action_id">
    <async>true</async>
    ...
</action>
この後にアクション URL に対して GET を実行すると、非同期タスクのステータス表示が提供されます。

表7.7 アクションのステータス

ステータス説明
pendingタスクがまだ開始されていない状態です。
in_progressタスクを実行中
completeタスクが正常に完了
failedタスクが失敗 (返される action 表現にはエラーの詳細を記述する fault が含まれる)
タスクが完了すると、そのアクションのデータは一定期間維持されます。この期間が満了した後に GET を実行すると、301 Moved Permanently となり、ターゲットリソースに戻るようリダイレクトされます。
GET /api/collection/resource_id/action/action_id HTTP/1.1
Accept: application/xml

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

<action id="action_id"
  href="/api/collection/resource_id/action/action_id">
    <status>
        <state>pending</state>
    </status>
    <link rel="parent" /api/collection/resource_id"/>
    <link rel="replay" href="/api/collection/resource_id/action"/>
</action>
アクション表現には rel 属性によって識別される複数のリンクも記載されます。

表7.8 アクションのリレーションシップ

タイプ説明
parentこのアクションのリソースに戻るリンク
replay元のアクション URI に戻るリンク。この URI に POST を実行すると、アクションが再度開始されます。

7.4.8. パーミッション

各リソースには permissions サブコレクションが含まれます。各 permissions には user、割り当てられた role、指定リソースなどが含まれます。 以下が例となります。
GET /api/collection/resource_id/permissions HTTP/1.1
Accept: application/xml

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

<permissions>
    <permission id="permission-id"
      href="/api/collection/resource_id/permissions/permission_id">
        <role id="role_id" href="/api/roles/role_id"/>
        <user id="user_id" href="/api/users/user_id"/>
        <resource id="resource_id" href="/api/collection/resource_id"/>
    </permission>
    ...
</permissions>
API ユーザーがリソースの permissions サブコレクションに対して、permission 表現および Content-Type: application/xml ヘッダーを記載した POST を送信すると、リソースは新規パーミッションを取得します。以下の例に示したように、各新規パーミッションには roleuser が必要です。
POST /api/collection/resource_id/permissions HTTP/1.1
Content-Type: application/xml
Accept: application/xml

<permission>
    <role id="role_id"/>
    <user id="user_id"/>
</permission>

HTTP/1.1 201 Created
Content-Type: application/xml

<permission id="permission_id"
  href="/api/resources/resource_id/permissions/permission_id">
    <role id="role_id" href="/api/roles/role_id"/>
    <user id="user_id" href="/api/users/user_id"/>
    <resource id="resource_id" href="/api/collection/resource_id"/>
</permission>

7.4.9. エラーの処理

エラーによっては、標準の HTTP ステータスコード以外に、詳細な説明を必要とするものがあります。たとえば API は、リソース状態の更新またはアクションの失敗を、応答エンティティー本文に fault 表現を指定して報告します。fault 表現には reasondetail の文字列が含まれます。クライアントは、fault または 応答ステータスコードに応じた、想定されるリソース表現を抽出することによって、失敗した要求に対応する必要があります。このような場合の対処方法は、各リソースの説明で明確に記載しています。
PUT /api/collection/resource_id HTTP/1.1
Accept: application/xml
Content-Type: application/xml

<resource>
    <id>id-update-test</id>
</resource>

HTTP/1.1 409 Conflict
Content-Type: application/xml

<fault>
    <reason>Broken immutability constraint</reason>
    <detail>Attempt to set immutable field: id</detail>
</fault>