RESTの実装

本セクションでは、Things CloudにおけるRESTベースインターフェースすべてに共通する側面を説明します。インターフェースはハイパーテキスト転送プロトコル、バージョン1.1を基本とし、HTTPSを使用します。

HTTPの用法

認証

認証ヘッダーの形式:

Authorization: Basic <<Base64 encoded credentials>>

一例がWikipediaエントリーに掲載されていますので、ご覧ください。

Things Cloudでは"Host"ヘッダー内のURLを使用して、認証対象となるテナントを判定します。あるいは、テナントのIDを「Authorization」ヘッダーの一部として、以下の形式で渡すこともできます。

<<tenant ID>>/<<user name>>:<<password>>

典型的に、テナントIDは、Things Cloudへアクセスするために使用しているURLの先頭部分に相当します。例えば、「mytenant.cumulocity.com」をURLとしてお使いの場合、"mytenant"がテナントIDに当たります。

JWT トークン認証

Things Cloud は JWT トークン認証をサポートしています。HTTP ヘッダに次を含める必要があります:

Authorization: Bearer <<Base64 エンコードされた JWT トークン>>

JWT トークンは、SHA-256 を利用した RSA 署名(RS256)でなければなりません。RSA鍵長の最小値は 512 bit です。ここ で鍵を試しに作ってみることができます。

公開鍵はテナントオプションにカテゴリ "token.publicKey" としてアップロードしなければなりません。

例:

POST /tenant/options
Host: ...
Authorization: Basic ...
Content-Type: application/vnd.com.nsn.cumulocity.option+json;ver=...
Accept: application/vnd.com.nsn.cumulocity.option+json;ver=...
{
    "category": "token.publicKey",
    "key": "myPubKey",
    "value": "..."
}

"key" は公開鍵の識別子です。これは JWT トークンの header で参照されます。"value" は PEM フォーマット(PKCS8形式をbase64エンコードしたもの)の公開鍵です。

これで、対応する鍵でJWT トークンと署名を生成できます。例えば、ここで試すことができます。

トークンフォーマット:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "myPubKey"
}
{
  "iss": "cumulocity",
  "aud": "myTenant",
  "sub": "username",
  "nbf": 1515678716,
  "exp": 1516629116
}
  • "kid" はテナントオプションで利用される公開鍵識別子です。
  • "iss" は "cumulocity" を指定する必要があります。
  • "aud" にはテナントIDを設定して下さい。
  • "sub" にはユーザーIDを設定して下さい。
  • "nbf" と "exp" にはそれぞれトークンの有効期間の開始/終了時間を UNIX 時間(1970年1月1日0時0分0秒(UTC)からの経過秒数を示す整数値)で設定して下さい。

テナントID、ユーザーIDがあっていないか、トークンが有効期間外か、署名が無効の場合 401 エラーが返却されます。

アプリケーション管理

Things Cloudではいわゆる「アプリケーション・キー」を使用して、デバイスから来るリクエストとアプリケーションからのトラフィックを区別します。アプリケーションを記述する場合、すべてのリクエストについて、以下のヘッダーを要素として渡します。

X-Cumulocity-Application-Key: <<application key>>

例えば、あなたのアプリケーションをThings Cloudの管理アプリケーションにおいて「myapp」というキーで登録した場合、以下を渡すことになります。

X-Cumulocity-Application-Key: myapp

これにより、あなたのアプリケーションを加入可能、課金可能なアプリケーションにすることができます。 デバイスを実装する場合、キーを渡さないでください。

必ず、アプリケーションから来るすべてのリクエストにおいて、このキーを渡してください。キーを除外してしまうと、リクエストはデバイスリクエストと見なされます(デバイスリクエスト数は課金対象です)。

制約のあるHTTPクライアント

HTTPにおけるGETメソッドとPOSTメソッドしか実行できないHTTPクライアントを使用している場合、付加的な「X-HTTP-METHOD」ヘッダーを介して、他のメソッドをエミュレートすることができます。単純に、POSTリクエストを発行してヘッダーを追加し、実際に実行したいRESTメソッドを指定するだけで結構です。例えば、「PUT」メソッドをエミュレートしたい場合、以下を使用することができます。

POST ...
X-HTTP-METHOD: PUT

処理モード

更新リクエスト(PUT、POST、DELETE)はすべて、いわゆる 処理モード で実行されます。初期設定の処理モードは PERSISTENT 処理モードです。これはすべての更新がThings Cloudデータベースとリアルタイム処理の双方に送られることを意味します。TRANSIENT 処理モードでは、更新をリアルタイム処理だけに送ります。リアルタイム処理の一環として、ユーザーは更新をデータベースに保存すべきか否かについて、ケースバイケースで都度、Things Cloud Event Languageスクリプト経由で決めることができます。QUIESCENT処理モードはPERSISTENT処理モードと同等の行動をしますが、リアルタイム通知は送信されません。現在、このQUIESCENT処理モードはメジャーメントとイベントにのみ適用できます。CEP処理モードはTRANSIENT 処理モードと同等の行動をしますが、リアルタイム通知は送信されません。現在、このCEP処理モードはメジャーメントとイベントにのみ適用できます。

更新リクエストの処理モードを明示的に制御するため、「X-Cumulocity-Processing-Mode」ヘッダーを、「PERSISTENT」「TRANSIENT」「QUIESCENT」「CEP」のいずれかの値に設定して使用することができます。

X-Cumulocity-Processing-Mode: TRANSIENT

認可

Things Cloud 宛に発行されるリクエストはすべて認可対象です。必要なパーミッションを判定するには、個別のリクエストに関するリファレンスに記載の「必要とされるロール」エントリーをご覧ください。さまざまなパーミッションについて、また Things Cloud における所有権の概念についてもっと詳しく知りたい場合、「セキュリティーに関する側面」セクションに記載の「パーミッションおよび所有権の管理」をご覧ください。

メディア種別

データは型毎に、独自のメディア種別と関連付けられます。一般的なメディア種別形式は以下の通りです。

application/vnd.com.nsn.cumulocity.<<type>>+json;ver=<<version>>;charset=UTF-8

メディア種別はそれぞれ、種別のバージョンを示す「ver」というパラメータを包含します。本ドキュメント公開時点で、最新バージョンは「0.9」です。メディア種別の完全な名称が、参照ガイドの各該当セクションに記載されています。一例として、現行バージョンにおけるエラーメッセージ向けのメディア種別は以下の通りです。

application/vnd.com.nsn.cumulocity.error+json;ver=0.9;charset=UTF-8

メディア種別はHTTPの「Content-Type」ヘッダーと「Accept」ヘッダーで使用されます。「Accept」ヘッダーをPOSTまたはPUTのリクエストにおいて指定すると、応答には新規作成されたオブジェクトまたは更新されたオブジェクトが含まれます。ヘッダーを指定しなければ、応答本文が空になります。

「ver」パラメータのないメディア種別を指定すると、利用可能な最も古いバージョンをサーバーが返します。「Accept」ヘッダーに同じメディア種別が含まれ、バージョンが複数ある場合、サーバーは最新のサポート対象バージョンでの表現を返します。

日付の形式

HTTPのリクエストと応答においてThings Cloudと交換されるデータは、JSON形式およびUTF-8の文字コードでコード化されます。Things Cloudでは以下の通り、ISO 8601形式のタイムスタンプと日付が許容・発信されます。

日付:YYYY-MM-DD
時刻:hh:mm:ss±hh:mm
タイムスタンプ:YYYY-MM-DDThh:mm:ss±hh:mm

曖昧にならないよう、すべての時刻とタイムスタンプにタイムゾーン情報が含まれなければなりません。プラス記号「+」は「%2B」としてコード化しなければならないという点を考慮に入れてください。

エラー報告

エラーが発生した場合、Things CloudはRFC2616に記載されている通りの標準HTTP応答コードを返します。クライアントは個別のコードだけでなく、コード区分(例:4xx)にも対処可能であるべきです。応答本文にはエラーに関する詳しい情報が含まれます。下記のエラーメディア種別の定義をご覧ください。一般的なエラーの解釈は以下の通りです。

コード 名称 説明
400 Bad Request リクエストは不正な形式の構文であるため、サーバーが理解できませんでした。クライアントはこのリクエストを未修正のまま繰り返さないでください。
401 Unauthorized 認証に失敗したか、または認証情報が要求されましたが提供されませんでした。
403 Forbidden このAPIにアクセスする権限がありません。
404 Not Found 指定された位置にリソースが見当たりません。
405 Method not allowed 採用されたHTTPメソッドはこのリソース上で使用することができません(例:読み取り専用リソース上での「POST」の使用)。
409 Update Conflict リソース更新が競合し、その間にエンティティが変わりました。
409 Duplicate このエンティティはデータソース内にすでに存在します。
413 Execution timeout, operation will be abandoned クエリの処理時間が長く、タイムアウトしました。
422 Invalid Data エンティティデータ形式に付随する一般的なエラー。
422 Non Unique Result リソース制約エラー。クエリからの非固有の結果。
422 Unprocessable entity リソースを処理できません。
500 Internal Server Error ソフトウェアシステムで内部エラーが発生し、リクエストを処理できませんでした。
503 Service Unavailable このサービスは現在ご利用いただけません。インスタンスの過負荷が原因か、または保守のため停止中です。数分後に再度お試しください。

RESTの用法

HTTP動詞の解釈

以下の通り、HTTP仕様に記載内容を使用します。

  • POST:新規リソースを作成します。応答の「Location」ヘッダー内で、新規作成されたリソースのURIが返されます。
  • GET:リソースを読み出します。
  • PUT:リクエストの内容に応じて既存のリソースを更新します。
  • DELETE:リソースを削除します。応答は「204 No Content」です。

PUTリクエストにリソースの一部しか含まれない、いわゆる「フラグメント」の状態である場合、含まれる部分だけが更新されます。フラグメントを排除するには、そのフラグメントの値がnullであるPUTリクエストを使用します。PUTは、別のURIによって識別されるサブリソースを更新することができません。

URI空間とURIテンプレート

URIテンプレートには波括弧で挟まれたプレースホルダーが含まれ、クライアントはこれを埋めてURIを生成する必要があります。 以下はイベントAPIリソースから抜粋の一例です。

Content-Type: application/vnd.com.nsn.cumulocity.eventApi+json;...
Content-Length: ...
{
  ...
  "events" : { "self" : "http://..." },
  "eventsForSourceAndType" : "http://...?type={type}&source={source}"
  ...
}

クライアントがイベントAPIの"eventsForSourceAndType"を実行する場合、「type」および「source」のプレースホルダーを付与する必要があります。各プレースホルダーの意味については、参照ガイドに記載の各インターフェースの説明をご覧ください。

インターフェース構造

一般的に、Things Cloud RESTのリソースは以下のパターンに従ってモデル化されます。

  • APIリソースが出発点となり、コレクションリソースを指すURIおよびURIテンプレート経由での実データへのアクセスを提供します。例えば上記のイベントAPIリソースは「events」URIと、イベントのコレクションにアクセスするための「eventsForSourceAndType」URIを提供します。
  • コレクションリソースはメンバーリソースを集約し、またコレクション内でのメンバーリソースの新規作成を可能にします。例えば、「events」コレクションリソースを介して、新規イベントを作成することができます。
  • 最終的に、個別のリソースの編集が可能となります。

クエリ結果のページング

コレクションリソースは、膨大な量のデータを1つのブロックでクライアントからサーバーへ渡すことを避けるよう、データのページングをサポートします。GETはコレクションに対して2つのクエリパラメータを受け付けるようリクエストし、例えば「pageSize」は返されるべきコレクションのエントリー数を表わします。初期設定では5つのエントリーが返されます。現在、1ページ当たりドキュメント数の上限は2,000個で、これを上回るページサイズがリクエストされた場合、上限まで削減されます。「currentPage」は返されることになるデータのスライスを定義し、「1」で始まります。初期設定では、最初のページが返されます。

便宜上、コレクションリソースは「next」および「prev」のリンクを提供し、これらはそれぞれ結果に関する次のページおよび前のページを読み出す役割を果たします。以下はマネージドオブジェクトのコレクションに関する応答の例です。

{
  "self" : "...",
  "managedObjects" : [
    ...
  ],
  "statistics" : {
    "totalPages" : 7,
    "pageSize" : 5,
    "currentPage" : 2
  },
  "prev" : "http://...?pageSize=5&Page=1",
  "next" : "http://...?pageSize=5&Page=3"
}

注意点として、「totalPages」プロパティは、計算コストが大きくなる可能性があるため、初期設定では複数の結果を持つクエリに対して返されません。「totalPages」を結果に含めるには、クエリパラメータ「withTotalPages=true」を追加します。

アクセス制限のあるユーザのクエリ結果ページング

もしユーザーにAPIリソースからデータを読み取るグローバルロールが無く、特定のドキュメントを読むための インベントリロール しかない場合はクエリ結果ページングに違いがあります:

  • 状況によっては、ユーザーがアクセスできるデータベース内のデータの方が多いにもかかわらず、レスポンスでは pageSize より要素が少なくなる場合があります。
  • 状況によっては、ユーザーがアクセスできるデータベース内のデータがなくなっても、応答に「次の」および「前」リンクが表示される場合があります。
  • 応答のプロパティー「currentPage」にはpagenumberが含まれていませんが、クエリのメカニズムによってまだ処理されていない次の要素のオフセットが含まれます。
  • クエリパラメータ「withTotalPages=true」は無効になり、「totalPages」プロパティの値は常にnullです。

上記の動作は、クエリーのメカニズムが要求ごとに最大10 * max(pageSize, 100) のドキュメントを繰り返し、ユーザーがアクセス可能なデータの全ページを収集できなかったにもかかわらず停止するという事実に起因します。次のページが要求されると、クエリのメカニズムは前回終了したところから反復を開始します。

ルートインターフェース

Things Cloudのさまざまなインターフェースを指すURIを見つけやすいよう、「root」インターフェースが用意されています。このルートインターフェースは、基礎的なAPIリソースをすべて集約するもので、"http://[テナントID].je1.thingscloud.ntt.com/platform/" を通じて利用可能です("je1"部分はお客さま環境によって異なる場合があります)。さまざまなAPIリソースについて詳しくは、本参照ガイドの該当APIセクションをご覧ください。

プラットフォーム[application/vnd.com.nsn.cumulocity.platformApi+json]

名称 種別 発生数 説明
self URI 1 このリソースへのリンク
inventory InventoryAPI 1 インベントリインターフェースをご覧ください。
identity IdentityAPI 1 識別情報インターフェースをご覧ください。
event EventAPI 1 イベントインターフェースをご覧ください。
measurement MeasurementAPI 1 メジャーメントインターフェースをご覧ください。
audit AuditAPI 1 監査インターフェースをご覧ください。
alarm AlarmAPI 1 アラームインターフェースをご覧ください。
user UserAPI 1 ユーザーインターフェースをご覧ください。
deviceControl DeviceControlAPI 1 デバイス制御インターフェースをご覧ください。

プラットフォームリソースの取得

応答本文:application/vnd.com.nsn.cumulocity.platformApi+json

応答例

HTTP/1.1 200 OK
Content-Type: application/vnd.com.nsn.cumulocity.platformApi+json;...
Content-Length: ...
{
  "self" : "<<URL to the platform API resource>>",
  "event" : {
    "self" : "<<URL to the event API resource>>",
    "events" : { "self" : "<<URL to event collection resource>>" },
    "eventsForSourceAndType" : "<<URL to event collection resource>>?type={type}&source={source}"
    ...
  },
  "inventory" : {
    ...
  },
  ...
}

一般的なメディア種別

エラー[application/vnd.com.nsn.cumulocity.error+json]

エラー種別は、リクエストが失敗した理由に関する詳細情報を提供します。

名称 種別 発生数 説明
error String 1 "<<リソース種別>>/<<エラー名>>"形式のエラー種別。例えば、あるオブジェクトがインベントリ内で見つからない場合、"inventory/notFound"として報告されます。
message String 1 エラーに関する短文説明
info URL 1 インターネット上に掲載されたエラー説明へのURL
details Error details 1 エラー詳細。DEBUGモードの場合に限り用意されます

エラーの詳細が以下の構造で提示されます。

名称 種別 発生数 説明
expectionClass String 1 このエラーの原因となった例外のクラス名。
exceptionMessage String 1 例外メッセージの内容。
expectionStackTrace String 1 例外のスタックトレース。
- - - エラー種別に応じた詳細な診断情報。

ページング統計 [application/vnd.com.nsn.cumulocity.pagingStatistics+json]

コレクションリソース向けのページング統計が以下の形式で提供されます。

名称 種別 発生数 説明
totalPages Integer 1 おおよそのレコード総数。
pageSize Integer 1 このクエリに含まれるレコードの最大件数。
currentPage Integer 1 全面的な一連の結果の範囲内で現在返されているページ。「1」から始まります。