RESTの実装

このセクションでは、Things CloudのすべてのRESTベースのインターフェースに共通する側面について説明します。 インターフェースは、 HTTPS を使用する Hypertext Transfer Protocol 1.1 に基づいています。

HTTPの用法

認証

リクエストはすべて認証が必要です。それには2つの方法があります。

1つ目はHTTPに“Authorization” ヘッダーを含む方法です。 2つ目はOAuth2 Authorization Code Grantになります。両方の形式は以下の通りになります。

これらについて下記で説明します。

認証ヘッダーの形式:

Authorization: Basic <<Base64 encoded credentials>>

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

OAuth2 Authorization Code Grantの形式:

Authorization: Bearer <<Base64 encoded access token>>

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

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

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

Things Cloudは2段階認証に対応しています。有効になっている場合、2段階認証トークンがヘッダーで送信されます。

TFAToken:<<tfa-token>>

トークンの有効期限が切れ、更新が必要な場合、バックエンドは応答ヘッダーを送信します。

TFATokenExpired:TFATokenExpired

JWT トークン認証

Things Cloud は JWT トークン認証に対応しています。

情報: このセクションで説明されている JWT トークン認証は非推奨です。ただし、今後さらなる通知があるまでは継続利用可能とする予定です。代わりに、次のセクションの OAuth 認可付与を利用するようにして下さい。

HTTP ヘッダには以下を含める必要があります:

Authorization: Bearer <<Base64 encoded JWT token>>

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
}

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

OAuth 認証コード付与

OAuth でのログインは Things Cloud側での適切な設定が必要です。設定をする事により、追加のボタンがログインページで表示され、選択可能になります。ボタンをクリック後認証サーバへリダイレクトされます。ログインが成功すれば、ユーザはThings Cloudへリダイレクトされます。

認証の詳細は Cookie で交換されます。これには二つのパーツがあり、一つ目はThings Cloudのプラットフォームで自動的に扱われる認証 Cookie です。2つ目はXSRF-TOKEN Cookie です。クライアントが Cookie を受けとると、全ての後続リクエストへその値をX-XSRF-TOKEN リクエストヘッダーに入力します。

OAuth 認証コード付与のフローは以下の通りです:

Authentication flow

ブラウザによる最初のリクエストは以下の通りです:

POST /tenant/loginOptions
Host: ...
Content-Type: application/vnd.com.nsn.cumulocity.loginOptionCollection+json;ver=...
Accept: application/vnd.com.nsn.cumulocity.loginOptionCollection+json;ver=...

応答:

{
    "loginOptions": [
        {
            "buttonName": "Login with oauth",
            "grantType": "AUTHORIZATION_CODE",
            "initRequest": "https://TENANT.je1.thingscloud.ntt.com/tenant/oauth?response_type=code&tenant_id=TENANT",
            "self": "http://TENANT.je1.thingscloud.ntt.com/tenant/loginOptions/oauth2",
            "type": "oauth2"
        },
        {
            "self": "http://dev-d.je1.thingscloud.ntt.com/tenant/loginOptions/basic",
            "type": "basic"
        }
    ],
    "self": "http://dev-d.je1.thingscloud.ntt.com/tenant/loginOptions/"
}

ここではログインに2つの選択肢があります。一つは基本のログイン、もう一つはOAuth2でのログインです。 ユーザーがOAuthを選択した場合、ブラウザは initRequestパラメーターで提供されたリクエストを呼び出す必要があります。

initRequest はリダイレクトを開始し、これによりユーザは認証情報を促されます。ログインが成功すると、ユーザーはブラウザへ再度リダイレクトされ、コードリクエストパラメータを取得する必要があります。次に、トークン用のコードの変換リクエストは以下になります:

POST /tenant/oauth?grant_type=authorization_code&code=<<code>>
Host: ...

正常な応答には本体はなく、次の応答ヘッダーがあります:

Set-Cookie: authorization=<<token>>;
Set-Cookie: XSRF-TOKEN=<<xsrfToken>>;

認証 Cookie の有効期限は2週間です。

アプリケーション管理

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形式のタイムスタンプと日付が許容され、発信されます。

Date: YYYY-MM-DD
Time: hh:mm:ss±hh:mm
Timestamp: YYYY-MM-DDThh:mm:ss±hh:mm

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

Things Cloud API データタイプ

Things Cloud のAPIは以下のデータタイプに制限されています。

タイプ 説明 サイズ 値の例
boolean true または false 1 bit true, false
int 2の補数整数 32 bit -2,147,483,648 から +2,147,483,647
long 2の補数整数 64 bit -9,223,372,036,854,775,808 から 9,223,372,036,854,775,807
float IEEE 754 浮動小数点 32 bit 1.40129846432481707e-45 から 3.40282346638528860e+38 (正数または負数)
double IEEE 754 浮動小数点 64 bit 4.94065645841246544e-324d から 1.79769313486231570e+308d (正数または負数)
string 文字列を表す - 最大 2,147,483,647 文字
datetime date , time または timestamp - ISO 8601 datetime

エラー報告

エラーが発生した場合、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 リソースを処理できません
429 Requests rate exceeds the limit 1秒あたりのリクエストレート制限を超えると、リクエストは遅延し、キュー番号制限を超えるまでキューに保持されます。制限を越えると、リクエストは破棄されエラーとなります
500 Internal Server Error ソフトウェアシステムで内部エラーが発生し、リクエストを処理できませんでした
503 Service Unavailable このサービスは現在ご利用いただけません。インスタンスの過負荷が原因か、または保守のため停止中です。数分後に再度お試しください

RESTの用法

HTTP動詞の解釈

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

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

URIスペースとURIテンプレート

クライアントは、リクエストで使用されるURIのレイアウトを仮定するのではなく、以前に返されたURIまたはURIテンプレートからURIを構築する必要があります。 ルートインターフェイスは、クライアントのエントリポイントを提供します。以下をご覧ください。

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

HTTP/1.1 200 OK
Content-Type: application/vnd.com.nsn.cumulocity.eventApi+json;...
Content-Length: ...

{
  ...
  "events" : { "self" : "http://..." },
  "eventsForSourceAndType" : "http://...?type={type}&source={source}"
  ...
}

クライアントは、返されるイベントの該当するタイプとソースデバイスを「タイプ」と「ソース」プレースホルダーに入力する必要があります。 これらのプレースホルダーについては、リファレンスガイドの各インターフェイスの説明に記載されています。

インターフェースの構造

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

クエリ結果のページング

コレクションリソースは、膨大な量のデータを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」を追加します。

備考: インベントリロールがユーザーに適用される場合、ユーザーからのクエリは、合計結果数が多くてもpageSizeの値未満の結果数を返します。

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

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

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

時間の範囲によるクエリ結果

次のパラメーターを使用して、指定した時間範囲のデータを取得します:

形式例:

dateTo=2019-04-20
dateTo=2019-04-20T08:30:00.000Z

パラメーターは任意です。これらのパラメーターで提供される値は包括的です。

ルートインターフェース

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 デバイス制御インターフェースをご覧ください

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

応答本体: 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 「<<resource type>>/<<error name>>」形式のエラータイプ。例えば、あるオブジェクトがインベントリ内で見つからない場合、「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]

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

名称 タイプ 発生回数 説明
totalRecords Integer 1 おおよその記録総数
pageSize Integer 1 クエリに格納された記録の最大数
currentPage Integer 1 「1」から始まる全ての結果セット内から返された現在のページ