Server Code の書式

Server Code を記述するときは、このページの書式に従って実装します。このページの内容は、Server Code の実行形態 の機能イメージがあることを前提に説明しています。

Server Code は、通常の JavaScript コードと同様に書くことができます。さらに Kii Cloud SDK for JavaScript を利用することで、Kii Cloud が提供する様々な機能を利用できます(Kii Cloud SDK for JavaScript の詳細については JavaScript リファレンスガイド を参照してください)。

同期的な Server Code と 非同期的な Server Code

Server Code は同期的・非同期的のいずれの方法でも書くことが可能です。いずれも基本的な構文は同じですが、非同期的な実行では、第 3 引数にコールバック関数が渡される点が異なります。

同期的な Server Code

同期的な Server Code の書式は以下のとおりです。関数が呼び出されると、コードが順に実行され、関数が return した時点で Server Code の実行が完了します。

function funcName(params, context) {
  // Your code comes here...
  return "Hello!";
}

非同期的な Server Code

非同期的な Server Code の書式は以下のとおりです。関数が終了しても Server Code の終了とは見なされず、第 3 引数のコールバック done が呼び出された後、関数から制御が戻った時点で実行が完了します(非同期的な実行 に示すように、done の呼び出し後に関数自身も終了する必要があります)。

function funcName(params, context, done) {
  // Your code comes here...
  done("Hello!");
}

ノンブロッキング API などの非同期的な呼び出しが前提の機能を使用する場合は、こちらの形式を使用する必要があります。

シンタックスの詳細

関数の型はすでに示したとおり、次のようになります。ここでは、Server Code が提供する機能ごとにパラメータなどの詳細について説明します。

// Synchronous function
function funcName(params, context) {
  // Your code comes here...
}

// Asynchronous function
function funcName(params, context, done) {
  // Your code comes here...
}

作成したエンドポイントを複数の機能から呼び出されるように設置した場合(たとえば、1 つの関数を手動実行とサーバートリガー起動の両方で共有するような場合)では、呼び出された状況に応じてパラメータの内容や API が返す値が変化します。

手動実行の場合

  • 関数名 funcName はエンドポイント名になります。クライアントから Server Code を実行する際には、このエンドポイント名を用いて実行対象関数を指定します。
  • 第 1 引数 params は、Server Code の実行時パラメータを取得するために利用します。クライアント側より渡した実行時パラメータを取得できます。たとえば、クライアントから username パラメータが渡された場合、params.username によって値を参照できます。

    なお、呼び出し元の IP アドレス等や SDK の種別などを取得できるパラメータは用意していません。必要な場合は、クライアント側から呼び出し元を識別できるパラメータを渡す必要があります。

  • 第 2 引数 context はアプリケーション関連パラメータ取得のために使用します。

    • getAppID メソッドを使うと AppID が取得できます。
    • getAppKey メソッドを使うと AppKey が取得できます。
    • getAccessToken メソッドを使うと、クライアント側で Server Code が呼び出されたときに指定されたアクセストークンを取得できます。
      • ログイン処理 を実行することで、クライアントと同じユーザーの権限で Server Code を実行できます(サンプルは こちら)。
      • さらに、このメソッドを使うと、Server Code がログイン済みユーザーから呼び出されたのか(有効なアクセストークンが返ります)、匿名ユーザーで呼び出されたのか(null が返ります)も判断できます。
    • getAppAdminContext メソッドを使うと アプリ管理者 のコンテキスト(KiiAppAdminContext)が取得できます。このコンテキストのメソッドからユーザーやグループの操作をアプリ管理者権限で実行できます(サンプルは こちら)。
  • 第 3 引数 done は 非同期的な実行の場合に、Server Code の実行結果をクライアントに返すためのコールバック関数です。下記の 非同期的な実行 も参照してください。

クライアントへの戻り値は、呼び出された関数の return で指定された値(同期的な実行の場合)、または、第 3 引数 done への引数値(非同期的な実行の場合)となります。

Server Code から複数の戻り値を返したい場合は、以下のように JSON を使うと容易です。呼び出し元では、JSON(JavaScript / REST)または JSONObject クラスのインスタンス(その他のクライアント SDK)として参照できます。

function main(params, context, done) {
    done({"bonusScore" : 100, "bonusTime" : 30});
}

クライアントからの呼び出し方の詳細は Server Code の手動実行 を参照してください。

Server Hook(サーバートリガー起動)の場合

  • 関数名 funcName はエンドポイント名になります。Server Code をコマンドラインツールで登録する際、このエンドポイント名を用いて実行するトリガーと対象関数を関連付けます。
  • 第 1 引数 params は、Server Code の実行を引き起こしたトリガーに関するパラメータを取得できます。引き起こしたトリガーごとに、以下の情報を取得できます。

    • Bucket 関連トリガーパラメータとパラメータの取得方法:

      トリガーパラメータ パラメータの取得方法
      実行を引き起こした Bucket のスコープ params.objectScope.appIDparams.objectScope.userID が値をもつ場合は "ユーザースコープ"
      params.objectScope.appIDparams.objectScope.groupID が値をもつ場合は "グループスコープ"
      params.objectScope.appIDparams.objectScope.thingID が値をもつ場合は "Thing スコープ"
      params.objectScope.appID のみが値をもつ場合は "アプリケーションスコープ"
      実行を引き起こした Bucket の ID params.bucketID
      実行を引き起こした Object の ID params.objectID
      実行を引き起こした Object の URI params.uri


      ここでは、Server Hook 設定ファイルで指定されたトリガーに基づいて、作成、削除、更新された Object の情報を取得できます。作成/更新時には、ID や URI から Object を作成して refresh することで、作成/更新後のキーと値のペアを取得できます(更新前/削除前のペアは取得できません)。

      params.uri に設定される値のフォーマットは、実体を引き起こした Object のスコープにより異なります:

      • アプリケーションスコープ:kiicloud://buckets/<bucketID>/objects/<objectID>
      • グループスコープ:kiicloud://groups/<groupID>/buckets/<bucketID>/objects/<objectID>
      • ユーザースコープ:kiicloud://users/<userID>/buckets/<bucketID>/objects/<objectID>
      • Thing スコープ:kiicloud://things/<thingID>/buckets/<bucketID>/objects/<objectID>
    • グループ関連トリガーパラメータとパラメータの取得方法:

      トリガーパラメータ パラメータの取得方法
      実行を引き起こしたグループの ID params.groupID
      実行を引き起こした Object の URI params.uri
      実行を引き起こした追加/削除済みユーザー 1 人の ID(トリガーがグループメンバーの追加/削除だった場合のみ通知、他のメンバーは含まない) params.members
      実行を引き起こされた際に、追加/削除に失敗したユーザー 1 人の ID(トリガーがグループメンバーの追加/削除だった場合のみ通知、他のメンバーは含まない) params.failed


      params.uri に設定される値のフォーマットは kiicloud://groups/<groupID> になります。

    • ユーザー関連トリガーパラメータとパラメータの取得方法:

      トリガーパラメータ パラメータの取得方法
      実行を引き起こしたユーザーの ID params.userID
      実行を引き起こしたユーザーの URI params.uri


      params.uri に設定される値のフォーマットは kiicloud://users/<userID> になります。

    • Thing 関連トリガーパラメータとパラメータの取得方法:

      トリガーパラメータ パラメータの取得方法
      実行を引き起こした Thing の ID params.thingID
      実行を引き起こした Thing の vendorThingID(トリガーが Thing の登録だった場合のみ通知) params.vendorThingID
      実行を引き起こした Thing の URI params.uri
      Thing オーナーとして追加または削除されたユーザーの ID(トリガーが Thing オーナーの登録または削除だった場合のみ通知) params.userID
      Thing オーナーとして追加または削除されたグループの ID(トリガーが Thing オーナーの登録または削除だった場合のみ通知) params.groupID
      更新されたフィールドとその値(トリガーが Thing 情報の更新だった場合のみ通知) params.values
      MQTT コネクションが正常切断したか異常切断したか。True の場合は正常切断、False の場合は異常切断(トリガーが Thing のオフライン化だった場合のみ通知) params.expected


      params.uri に設定される値のフォーマットは kiicloud://things/<thingID> になります。

      params.values には、追加または更新されたフィールドとその値が JSON 形式で渡されます。削除されたフィールドには null が記録されます。

      一例として、以下のように Thing 情報が更新された場合を考えます。

      • フィールド "_lot" が、"LOT_12345" という値とともに追加された。
      • フィールド "_firmwareVersion" の値が "updated_version" に更新された。
      • カスタムフィールド "custom_field_1" が、"new_value_1" という値とともに追加された。
      • カスタムフィールド "custom_field_2" の値が "updated_value_2" に更新された。
      • カスタムフィールド "custom_field_3" が削除された。

      この場合、param.values には以下の JSON データが渡されます。

      {
          "_lot": "LOT_12345",
          "_firmwareVersion": "updated_version",
          "custom_field_1": "new_value_1",
          "custom_field_2": "updated_value_2",
          "custom_field_3": null
      }
      
    • Installation 関連トリガーパラメータとパラメータの取得方法:

      トリガーパラメータ パラメータの取得方法
      デバイスをインストール/アンインストールしたユーザーの ID(FCM、APNs、JPush) params.userID
      デバイスをインストール/アンインストールした Thing の ID(MQTT) params.thingID
      実行を引き起こしたデバイスインストール/アンインストールの ID(Installation ID の値で、Installation Registration ID ではない) params.installationID
      実行を引き起こしたデバイスインストール/アインインストールの URI params.uri


      params.uri に設定される値のフォーマットは kiicloud://installations/<installationID> になります。

  • 第 2 引数 context はアプリケーション関連パラメータ取得のために使用します。

    • getAppID メソッドを使うと AppID が取得できます。
    • getAppKey メソッドを使うと AppKey が取得できます。
    • getAccessToken メソッドを使うと、トリガーが実行される原因となったリクエストに指定されていたアクセストークンを取得できます。たとえば、Bucket 変更のトリガーでは、その Bucket を書き換えたユーザーのアクセストークンを取得できます。
      • ログイン処理 を実行することで、クライアントと同じユーザーの権限で Server Code を実行できます(サンプルは こちら)。
      • さらに、このメソッドを使うと、トリガーの対象がログイン済みユーザーから変更されたのか(有効なアクセストークンが返ります)、匿名ユーザーで変更されたのか(null が返ります)も判断できます。
    • getAppAdminContext メソッドを使うと アプリ管理者 のコンテキスト(KiiAppAdminContext)が取得できます。このコンテキストのメソッドからユーザーやグループの操作をアプリ管理者権限で実行できます(サンプルは こちら)。
  • 第 3 引数 done は 非同期的な実行の場合に、Server Code の実行を完了するためのコールバック関数です。コールバック関数への引数は特に意味を持ちません。下記の 非同期的な実行 も参照してください。

サーバートリガー起動では、Server Code からの戻り値は特に意味を持たないため、同期的な実行での return ステートメントの戻り値や、done への引数値は無視されます。

Server Hook(スケジュール起動)の場合

  • 関数名 funcName はエンドポイント名になります。Server Code をコマンドラインツールで登録する際、このエンドポイント名を用いてスケジュール起動する日時と対象関数を関連付けます。
  • 第 1 引数 params は、Server Hook 設定ファイルで記述したパラメータの値が渡されます。たとえば、Server Hook 設定ファイル"arg1" : "xxxx" と記述されていた場合、params.arg1 より xxxx を取得できます。
  • 第 2 引数 context はアプリケーション関連パラメータ取得のために使用します。
    • getAppID メソッドを使うと AppID が取得できます。
    • getAppKey メソッドを使うと AppKey が取得できます。
    • getAccessToken メソッドは常に null を返します。
    • getAppAdminContext メソッドを使うと アプリ管理者 のコンテキスト(KiiAppAdminContext)が取得できます。このコンテキストのメソッドからユーザーやグループの操作をアプリ管理者権限で実行できます(サンプルは こちら)。
  • 第 3 引数 done は 非同期的な実行の場合に、Server Code の実行を完了するためのコールバック関数です。引数値は下記に示す戻り値として記録されます。下記の 非同期的な実行 も参照してください。

スケジュール起動では、Server Code からの戻り値は実行履歴に保存され、コマンドラインツール を使って確認できます。呼び出された関数の return で指定された値(同期的な実行の場合)、または、第 3 引数 done への引数値(非同期的な実行の場合)が記録されます。

Thing-IF のトリガーの場合

Thing-IF のトリガーから起動する Server Code は、手動実行の場合 と同じ方法で記述します。トリガーと手動実行は、呼び出し方法だけが異なります。

Server Code から返された戻り値は、Thing Interaction Framework に蓄積され、Thing-IF SDK の機能によってモバイルアプリから取得できます。

非同期的な実行

非同期的な実行では、第 3 引数のコールバック関数の実行、または、例外の throw によって Server Code の終了を識別します。特に結果を返す必要がない場合やエラー終了する場合においても、処理の完了時に必ずコールバック関数を実行してください(例外を throw した場合には呼び出しは不要です)。実行しなかった場合、タイムアウト例外が発生します。

特に、コールバック関数の failure を省略した場合や、Promise の利用時に catch ハンドラーを適切に記述しなかった場合、done() が呼び出されないパスが存在することになります。この場合、Server Code がタイムアウトするためご注意ください。

done コールバック関数を実行しても Server Code 自体は終了しないことに注意してください。たとえば以下の Server Code を実行した場合、done("ERROR!!") が実行された後でも続けて done("SUCCESS!!") が実行されます。

function asyncFunc(params, context, done) {
  if (!context.getAccessToken()) {
    done("ERROR!!");
    // You need a return statement here.
  }
  done("SUCCESS!!");
}

実際の処理では、必ずコールバックの後に return で関数を終了するなどして、コールバック関数を 1 回だけ呼び出すようなロジックにする必要があります。コールバック関数が 2 回以上呼び出された場合、初めの値が戻り値となりますが、2 回目以降の呼び出しは Warning として 開発者ログ に記録されます。

また、ノンブロッキング API を使用する場合、done の呼び出しを行った後でも、ノンブロッキング API へのコールバックは実行されます。たとえば、以下の Server Code では、ログイン終了のコールバック関数は実行されて、ログが出力されます。下記のコードの done は、実際に実行される処理の最後(ここではコールバックの内部)で呼び出すように修正する必要があります。

function asyncFunc(params, context, done) {
  KiiUser.authenticate("aaaa", "bbbb", {
    success: function(theUser) {
      console.log("User authenticated!");
      // Call the done() function here.
    },
    failure: function(theUser, errorString) {
      console.log("Error authenticating: " + errorString);
      // Call the done() function here.
    }
  });
  done("OK");  // You shouldn't call the done() function here.
}

非同期的な実行を行うと、ネストが深くなって可読性が低下します。JavaScript SDK がサポートしている Promise の利用をおすすめします。また、jQuery.Deferred() も利用できます。

タイムアウト

タイムアウトが発生した場合、通常は例外がスローされます。

タイムアウト発生時にクライアントに特定の値を返すことも可能です。この場合は、以下の例のように context オブジェクトに返したい値を設定します。

function main(params, context, done) {
    context._timeoutReponse = {customField: "my_custom_message"};
}

上記の指定を行った場合、タイムアウト時に例外はスローされず正常終了として処理されます。クライアント側では、指定した値を通常の実行結果と同様に取得できます。詳しくは こちら をご参照ください。