Server Code の手動実行

Server Code はクライアントよりいつでも手動で実行できます。実行の際には、クライアント側より Server Code に実行時パラメータを渡すことができます。

Server Code を実行する方法を見ていきましょう。以下の Server Code が Kii Cloud に設置されていると仮定します。

function main(params, context, done) {
  var user = KiiUser.userWithUsername(params.username,
                                      params.password);
  user.register({
    success: function(user) {
      done(user.getUsername());
    },
    failure: function(user, errorString) {
      done(errorString);
    }
  });
}

このサンプルコードは こちらで例示したもの と同じものです。クライアントより実行時パラメータとして渡されたユーザーネームとパスワードを用いてユーザー登録処理を行います(友人の代わりに新規アカウント作成を代行するケースなどを想定したサンプル)。

なお、Server Code 内の success と failure は、クライアントでの成功と失敗に対応しない点にご注意ください。このサンプルコードの場合、Server Code 内の処理が failure で失敗しても、クライアントではエラー文字列を正常に受け取れるため、呼び出しは成功となります。クライアントのエラーは、Server Code の呼び出しそのものができなかった場合です。Server Code 内のエラーを返したい場合は、戻り値に成功/失敗のステータスを含めるように実装します。

REST API で Server Code を実行する

REST API で Server Code を実行する例を以下に挙げます。

curl -v -X POST \
  -H "Authorization: Bearer {ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  "https://api-jp.kii.com/api/apps/{APP_ID}/server-code/versions/current/main" \
  -d '{"username": "name_of_my_friend", "password": "password_for_my_friend"}'
  • 実行時パラメータとして "username" と "password" の値をサーバーに渡しています。
  • API をコールする際に、実行対象エンドポイント(関数)として "main" を指定しています。
  • アクセストークンの指定は省略することもできます。省略した場合は匿名ユーザーが Server Code を実行したと見なされます。

この結果 Server Code の "main" という関数が実行されます。サンプルの Server Code では KiiUser.userWithUsername() メソッドにおいて実行時パラメータを使用しています。実行時パラメータのキー("usename" と "password")が、Server Code 内のものと一致していることがわかります。

実行の結果、以下の様な応答が返されます。

< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Access-Control-Allow-Origin: *
< X-Step-count: 3
< X-Environment-version: 0
< Content-Type: application/json;charset=UTF-8
< Cache-Control: max-age=0
< Content-Length: 27
< Accept-Ranges: bytes
< Date: Tue, 23 Jul 2013 03:57:28 GMT
< X-Varnish: 1572330455
< Age: 0
< Via: 1.1 varnish
< Connection: keep-alive
<
* Connection #0 to host js-box-tmp.internal.kii.com left intact
{"returnedValue":"name_of_my_friend"}
* Closing connection #0

この応答例のように Server Code の実行結果は "returnedValue" フィールドに入ります。またステップ数が "X-Step-count" ヘッダの値、実行した Node.js のバージョンが "X-Environment-version" ヘッダの値として返されます。

Server Code を手動実行して別の Server Code を呼び出すことはできません。実行すると、HTTP ステータス 409 で "OPERATION_NOT_ALLOWED" エラーになります。

戻り値の型

Server Code は様々な型のデータを実行結果として返すことができます。Server Code の実行結果がどのように返されるかを以下の表にまとめます(ここでは、非同期的に書かれたコードにおける結果返却用コールバック関数の名前が "done" であると仮定しています)。

同期的に書かれた Server Code における実行結果 非同期的に書かれた Server Code における実行結果 クライアントへの応答内容
return 1; done(1); {"returnedValue":1}
return "resp"; done("resp"); {"returnedValue":"resp"}
return true; done(true); {"returnedValue":true}
return {name:"Kii", zip:"123456"}; done({name:"Kii", zip:"123456"}); {"returnedValue":{name:"Kii", zip:"123456"}}
return ["one", "two"]; done(["one", "two"]); {"returnedValue":["one", "two"]}

タイムアウト

制限事項 に記載されているように、Server Code の実行時間が 20000 msec を超えるとタイムアウトが発生します。

タイムアウトが発生した場合、通常は次のような 400 応答が返されます。

{
  "errorCode" : "ENDPOINT_INVOCATION_ERROR",
  "message" : "Error found while executing the developer-defined code",
  "details" : {
    "errorCode" : "EXECUTION_TIMEOUT",
    "message" : "execution timeout. limit=20000ms"
  }
}

Server Code の書式 で解説した方法でタイムアウト時に返却する値を設定した場合は、400 応答ではなく 200 応答が返されます。この際、次のように _timeoutResponse フィールドの値として Server Code 側で設定した値が返されます。

{
  "returnedValue":{
    "_timeoutResponse":{
      "customField": "my_custom_message"
    }
  }
}

設定した値は 通常の実行結果 と同様に取得可能です。

JavaScript エンジンの指定

Server Code を実行する際に使用する JavaScript エンジン のバージョンを指定できます。指定されたバージョンは、Server Code の登録時に設定されているバージョンより優先されます。

JavaScript エンジンの指定例を以下に示します。

curl -v -X POST \
  -H "Authorization: Bearer {ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  "https://api-jp.kii.com/api/apps/{APP_ID}/server-code/versions/current/main?environment-version=6" \
  -d '{"username": "name_of_my_friend", "password": "password_for_my_friend"}'

JavaScript エンジンは、URL の environment-version パラメーターで指定します。指定できる値は、以下のとおりです。指定した JavaScript エンジンが利用できない場合はエラーを返します。

environment-version を省略した場合は、Server Code の実行対象のバージョンに設定されている JavaScript エンジン、または、デフォルトの JavaScript エンジンが使用されます。

バージョン 備考
0 Node.js 0.10.X デフォルトの JavaScript エンジン、2017/10/31 まで指定可能
6 Node.js 6.X 2017/10/31 以降のデフォルトの JavaScript エンジン

Android SDK より Server Code を実行する

Android SDK より Server Code を実行する例を以下に挙げます。

  • // Instantiate the endpoint.
    KiiServerCodeEntry entry = Kii.serverCodeEntry("main");
    
    try {
      // Set parameters.
      JSONObject rawArg = new JSONObject();
      rawArg.put("username", "name_of_my_friend");
      rawArg.put("password", "password_for_my_friend");
    
      // Create a container of the parameters.
      KiiServerCodeEntryArgument arg = KiiServerCodeEntryArgument
          .newArgument(rawArg);
    
      // Execute the server code.
      KiiServerCodeExecResult res = entry.execute(arg);
    
      // Parse the result.
      JSONObject returned = res.getReturnedValue();
      String newUser = returned.getString("returnedValue");
    
      // Get the number of the executed steps.
      int steps = res.getExecutedSteps();
    
      // Get the version of Node.js on which the server code was executed.
      KiiServerCodeEnvironmentVersion executedVersion = res.getEnvironmentVersion();
    
    } catch (AppException e) {
      // Handle the error.
    } catch (IOException e) {
      // Handle the error.
    } catch (JSONException e) {
      // Handle the error.
    }
  • // Instantiate the endpoint.
    KiiServerCodeEntry entry = Kii.serverCodeEntry("main");
    
    // Set parameters.
    JSONObject rawArg = new JSONObject();
    try {
      rawArg.put("username", "name_of_my_friend2");
      rawArg.put("password", "password_for_my_friend");
    } catch (JSONException e) {
      // Handle the error.
    }
    
    // Create a container of the parameters.
    KiiServerCodeEntryArgument arg = KiiServerCodeEntryArgument
        .newArgument(rawArg);
    
    // Execute the server code.
    entry.execute(arg, new KiiServerCodeEntryCallback() {
      public void onExceuted(KiiServerCodeEntry entry, KiiServerCodeEntryArgument argument,
                             KiiServerCodeExecResult res, Exception exception) {
        if (exception != null) {
          // Handle the error.
          return;
        }
    
        try {
          // Parse the result.
          JSONObject returned = res.getReturnedValue();
          String newUser = returned.getString("returnedValue");
    
          // Get the number of the executed steps.
          int steps = res.getExecutedSteps();
    
          // Get the version of Node.js on which the server code was executed.
          KiiServerCodeEnvironmentVersion executedVersion = res.getEnvironmentVersion();
        } catch (JSONException e) {
          // Handle the error.
        }
      }
    });

ここでは以下の処理が行われています。

  • 実行対象エンドポイント名(関数名)を指定して serverCodeEntry() メソッドを実行し、KiiServerCodeEntry インスタンスを作成。KiiServerCodeEnvironmentVersion 引数を指定して、Server Code の実行に使用する JavaScript エンジンを指定することもできます。
  • 実行時パラメータ(今回の例ではユーザー名とパスワード)を JSON オブジェクトに格納し、これを指定して newArgument() メソッドを実行し、KiiServerCodeEntryArgument インスタンスを作成。この際、実行時パラメータのキーを Server Code 内のキーと一致させてください(今回の例では "username" と "password")。
  • 実行時パラメータを指定して execute() メソッドを実行し、Server Code を実行。
    • ユーザーがログインしている場合、Kii Cloud はこのユーザーにより Server Code が実行されたものと見なします。
    • ユーザーがログインしていない場合、Kii Cloud は匿名ユーザーにより Server Code が実行されたものと見なします。
  • getReturnedValue() メソッドを実行して、実行結果を取得。
  • (必要に応じて)getExecutedSteps() メソッドを実行して、実行ステップ数を取得。
  • (必要に応じて)getEnvironmentVersion() メソッドを実行して、Node.js のバージョンを取得。

getReturnedValue() メソッドは、戻り値の型 で例示したような、Server Code を実行した結果が "returnedValue" フィールドに格納された JSON オブジェクトを返します。実際の結果を抽出するには、適切なメソッドを実行してください。今回の例の場合は getString() メソッドを使い、新規に作成されたユーザー名の取得を行っています。

タイムアウト時に返却する値を設定した場合、同様に getReturnedValue() メソッドを使って値を取得します。メソッドで取得可能な JSON オブジェクトは タイムアウト をご参照ください。

iOS SDK より Server Code を実行する

iOS SDK より Server Code を実行する例を以下に挙げます。

Swift 3:

  • // Instantiate the endpoint.
    let entry = Kii.serverCodeEntry("main")
    
    // Set parameters.
    let argDict = ["username":"name_of_my_friend","password":"password_for_my_friend"]
    
    // Create a container of the parameters.
    let argument = KiiServerCodeEntryArgument(dictionary:argDict)
    
    let result : KiiServerCodeExecResult
    
    do{
      // Execute the server code.
      result = try entry.executeSynchronous(argument)
    }catch(let error as NSError){
      // Handle the error.
      return
    }
    // Parse the result.
    let returnedDict = result.returnedValue()
    let newUser = returnedDict?["returnedValue"];
    
    // Get the number of the exectued steps.
    let execSteps : Int = result.executedSteps()
    
    // Get the version of Node.js on which the server code was executed.
    let executedVersion = result.environmentVersion()
  • // Instantiate the endpoint.
    let entry = Kii.serverCodeEntry("main")
    
    // Set parameters.
    let argDict = ["username":"name_of_my_friend","password":"password_for_my_friend"]
    
    // Create a container of the parameters.
    let argument = KiiServerCodeEntryArgument(dictionary:argDict)
    
    // Execute the server code.
    entry.execute(argument) { (retEntry : KiiServerCodeEntry, retArg : KiiServerCodeEntryArgument?, result : KiiServerCodeExecResult?, error : Error?) in
      if error != nil {
        // Handle the error.
        return
      }
    
      // Parse the result.
      let returnedDict = result?.returnedValue()
      let newUser = returnedDict?["returnedValue"];
    
      // Get the number of the exectued steps.
      let execSteps : Int = result!.executedSteps()
    
      // Get the version of Node.js on which the server code was executed.
      let executedVersion = result.environmentVersion()
    }

Objective-C:

  • // Instantiate the endpoint.
    KiiServerCodeEntry* entry =[Kii serverCodeEntry:@"main"];
    
    // Set parameters.
    NSDictionary* argDict= [NSDictionary dictionaryWithObjectsAndKeys:
                             @"name_of_my_friend", @"username",
                             @"password_for_my_friend", @"password", nil];
    
    // Create a container of the parameters.
    KiiServerCodeEntryArgument* argument= [KiiServerCodeEntryArgument argumentWithDictionary:argDict];
    
    // Execute the server code.
    NSError* error = nil;
    KiiServerCodeExecResult* result = [entry executeSynchronous:argument
                                                      withError:&error];
    if (error != nil) {
      // Handle the error.
      return;
    }
    
    // Parse the result.
    NSDictionary *returnedDict = [result returnedValue];
    NSString *newUser = [returnedDict objectForKey:@"returnedValue"];
    
    // Get the number of the exectued steps.
    int execSteps = (int)[result executedSteps];
    
    // Get the version of Node.js on which the server code was executed.
    KiiServerCodeEnvironmentVersion executedVersion = [result environmentVersion];
  • // Instantiate the endpoint.
    KiiServerCodeEntry* entry =[Kii serverCodeEntry:@"main"];
    
    // Set parameters.
    NSDictionary* argDict= [NSDictionary dictionaryWithObjectsAndKeys:
                             @"name_of_my_friend", @"username",
                             @"password_for_my_friend", @"password", nil];
    
    // Create a container of the parameters.
    KiiServerCodeEntryArgument* argument= [KiiServerCodeEntryArgument argumentWithDictionary:argDict];
    
    // Execute the server code.
    NSError* error = nil;
    [entry execute:argument
         withBlock:^(KiiServerCodeEntry *entry, KiiServerCodeEntryArgument *argument, KiiServerCodeExecResult *result, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
    
      // Parse the result.
      NSDictionary *returnedDict = [result returnedValue];
      NSString *newUser = [returnedDict objectForKey:@"returnedValue"];
    
      // Get the number of the exectued steps.
      int execSteps = (int)[result executedSteps];
    
      // Get the version of Node.js on which the server code was executed.
      KiiServerCodeEnvironmentVersion executedVersion = [result environmentVersion];
    }];

ここでは以下の処理が行われています。

  • 実行対象エンドポイント名(関数名)を指定して serverCodeEntry(_:) メソッドを実行し、KiiServerCodeEntry インスタンスを作成。environmentVersion 引数を指定して、Server Code の実行に使用する JavaScript エンジンを指定することもできます。
  • 実行時パラメータ(今回の例ではユーザー名とパスワード)を NSDictionary に格納し、これを指定して KiiServerCodeEntryArgument(dictionary:) メソッドを実行し、KiiServerCodeEntryArgument インスタンスを作成。この際、実行時パラメータのキーを Server Code 内のキーと一致させてください(今回の例では "username" と "password")。
  • 実行時パラメータを指定して execute(_:) メソッドを実行し、Server Code を実行。
    • ユーザーがログインしている場合、Kii Cloud はこのユーザーにより Server Code が実行されたものと見なします。
    • ユーザーがログインしていない場合、Kii Cloud は匿名ユーザーにより Server Code が実行されたものと見なします。
  • returnedValue() メソッドを実行して、実行結果を取得。
  • (必要に応じて)executedSteps() メソッドを実行して、実行ステップ数を取得。
  • (必要に応じて)environmentVersion() メソッドを実行して、Node.js のバージョンを取得。

returnedValue() メソッドは、戻り値の型 で例示したような、Server Code を実行した結果が "returnedValue" フィールドに格納された NSDictionary を返します。実際の結果を抽出するには、適切なメソッドを実行してください。

タイムアウト時に返却する値を設定した場合、同様に returnedValue() メソッドを使って値を取得します。メソッドで取得可能な NSDictionary は タイムアウト をご参照ください。

Unity SDK より Server Code を実行する

Unity SDK より Server Code を実行する例を以下に挙げます。

// Instantiate the endpoint.
KiiServerCodeEntry entry = Kii.ServerCodeEntry("main");

// Set parameters.
JsonObject rawArg = new JsonObject();
rawArg.Put("username", "name_of_my_friend");
rawArg.Put("password", "password_for_my_friend");

// Create a container of the parameters.
KiiServerCodeEntryArgument arg = KiiServerCodeEntryArgument
    .NewArgument(rawArg);

// Execute the server code.
entry.Execute(arg, (KiiServerCodeEntry retEntry, KiiServerCodeEntryArgument args,
                    KiiServerCodeExecResult result, Exception e) => {
  if (e != null)
  {
    // Handle the error.
    return;
  }

  // Parse the result.
  JsonObject returned = result.ReturnedValue;
  string newUser = returned.GetString("returnedValue");

  // Get the number of the executed steps.
  int steps = result.ExecutedSteps;

  // Get the version of Node.js on which the server code was executed.
  KiiServerCodeEnvironmentVersion executedVersion = result.EnvironmentVersion;
});

ここでは以下の処理が行われています。

  • 実行対象エンドポイント名(関数名)を指定して ServerCodeEntry() メソッドを実行し、KiiServerCodeEntry インスタンスを作成。KiiServerCodeEnvironmentVersion 引数を指定して、Server Code の実行に使用する JavaScript エンジンを指定することもできます。
  • 実行時パラメータ(今回の例ではユーザー名とパスワード)を JSON オブジェクトに格納し、これを指定して NewArgument() メソッドを実行し、KiiServerCodeEntryArgument インスタンスを作成。この際、実行時パラメータのキーを Server Code 内のキーと一致させてください(今回の例では "username" と "password")。
  • 実行時パラメータを指定して Execute() メソッドを実行し、Server Code を実行。
    • ユーザーがログインしている場合、Kii Cloud はこのユーザーにより Server Code が実行されたものと見なします。
    • ユーザーがログインしていない場合、Kii Cloud は匿名ユーザーにより Server Code が実行されたものと見なします。
  • ReturnedValue プロパティで、実行結果を取得。
  • (必要に応じて)ExecutedSteps プロパティで、実行ステップ数を取得。
  • (必要に応じて)EnvironmentVersion プロパティで、Node.js のバージョンを取得。

ReturnedValue プロパティは、戻り値の型 で例示したような、Server Code を実行した結果が "returnedValue" フィールドに格納された JSON オブジェクトです。実際の結果を抽出するには、適切なメソッドを実行してください。今回の例の場合は GetString() メソッドを使い、新規に作成されたユーザー名の取得を行っています。

タイムアウト時に返却する値を設定した場合、同様に ReturnedValue プロパティより値を取得します。プロパティより取得可能な JSON オブジェクトは タイムアウト をご参照ください。

JavaScript SDK より Server Code を実行する

JavaScript SDK より Server Code を実行する例を以下に挙げます。

// Instantiate the endpoint.
var entry = Kii.serverCodeEntry("main");

// Set parameters.
var arg = {"username":"name_of_my_friend", "password":"password_for_my_friend"};

// Execute the server code.
entry.execute(arg,{

    success: function(entry, argument, execResult) {

      // Parse the result.
      var returned = execResult.getReturnedValue();
      var newUser = returned["returnedValue"];

      // Get the number of the executed steps.
      var steps = execResult.getExecutedSteps();

      // Get the version of Node.js on which the server code was executed.
      var environmentVersion = execResult.getEnvironmentVersion();
    },

    failure: function(entry, argument,execResult, anErrorString) {
      // Handle the error.
    }
  }
);

ここでは以下の処理が行われています。

  • 実行対象エンドポイント名(関数名)を指定して serverCodeEntry() メソッドを実行し、KiiServerCodeEntry インスタンスを作成。environmentVersion 引数を指定して、Server Code の実行に使用する JavaScript エンジンを指定することもできます。
  • 実行時パラメータ(今回の例ではユーザー名とパスワード)を JSON オブジェクトに準備します。この際、実行時パラメータのキーを Server Code 内のキーと一致させてください(今回の例では "username" と "password")。
  • 実行時パラメータを指定して execute() メソッドを実行し、Server Code を実行。
    • ユーザーがログインしている場合、Kii Cloud はこのユーザーにより Server Code が実行されたものと見なします。
    • ユーザーがログインしていない場合、Kii Cloud は匿名ユーザーにより Server Code が実行されたものと見なします。
  • getReturnedValue() メソッドを実行して、実行結果を取得。
  • (必要に応じて)getExecutedSteps() メソッドを実行して、実行ステップ数を取得。
  • (必要に応じて)getEnvironmentVersion() メソッドを実行して、Node.js のバージョンを取得。

getReturnedValue() メソッドは、戻り値の型 で例示したような、Server Code を実行した結果が "returnedValue" フィールドに格納された JSON オブジェクトを返します。実際の結果を抽出するには、適切なメソッドを実行してください。

タイムアウト時に返却する値を設定した場合、同様に getReturnedValue() メソッドを使って値を取得します。メソッドで取得可能な JSON オブジェクトは タイムアウト をご参照ください。

Server Code を手動実行して別の Server Code を呼び出すことはできません。実行すると、HTTP ステータス 409 で "OPERATION_NOT_ALLOWED" エラーになります。

Thing SDK Embedded より Server Code を実行する

Thing SDK Embedded を使うと、Thing から Server Code を実行できます。実行方法は Server Code の実行 をご覧ください。