Manually Executing Server Code

You can also execute your server code directly at any time from the client side. When you directly execute server code, you can also pass some custom parameters.

Let's explore how you can manually execute server code. Let us assume that you've deployed the following server code.

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);
    }
  });
}

This is the same sample code we've presented in Writing Server Code. The sample code is expecting to receive a username and password from a client device as the custom parameter, and it will execute the sign-up process with these parameters (e.g. allowing an application user to sign up on behalf of his/her friend).

Note that the success/failure status within the server code doesn't match that on the client. In this sample code, the call from the client will be successful even if the process within the server code fails because the client will receive the error string successfully. The client will fail when it cannot call the server code. In order to send the error in the server code to the client, implement the server code to return the success/failure status of it as the return value.

Executing server code via the REST API

Here is an example of executing server code via the REST API.

curl -v -X POST \
  -H "Authorization: Bearer {ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  "https://api.kii.com/api/apps/{APP_ID}/server-code/versions/current/main" \
  -d '{"username": "name_of_my_friend", "password": "password_for_my_friend"}'
  • We pass the values for "username" and "password" as the data.
  • We call the API with the target endpoint ("main").
  • The access token is optional. If it is omitted, Kii Cloud interprets the server code as being executed by an anonymous user.

This will execute the function "main" in the server code. As you see in the sample server code, two custom parameters are used in the KiiUser.userWithUsername() method. Notice that the code is using the keys ("username" and "password") when fetching the corresponding values.

The response will be like the followings:

< 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

You can see that the execution result is returned in the "returnedValue" field. Also, the number of the executed steps is returned in the "X-Step-count" header and the version of Node.js on which the server code was executed is returned in the "X-Environment-version" header.

You cannot execute server code by manually executing another server code. If you attempt to do so, you will get an HTTP 409 response with the "OPERATION_NOT_ALLOWED" error.

Data types of return values

Your server code can return other data types as the execution result. Check the following table to see how the execution result is returned to the client (Here we assume that the name of callback function for returning the result is "done" in the asynchronous mode).

Statement in the synchronous code Statement in the asynchronous code Return value in the response
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"]}

Timeout

As described in the Limitations, the timeout occurs when the server code execution time goes over 20000 msec.

When the timeout occurs, Kii Cloud usually returns a 400 response as follows:

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

If you've set the value to return after the timeout as described in Server code syntax, you will get a 200 response instead of a 400 response. In this case, the value specified in the server code will be set in the _timeoutResponse as follows:

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

You can get the value just like the normal execution result.

Specifying the JavaScript engine

You can specify the version of the JavaScript engine on which server code is executed. The specified version overrides the version set at the server code registration.

Below is an example of specifying the JavaScript engine.

curl -v -X POST \
  -H "Authorization: Bearer {ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  "https://api.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"}'

Specify the JavaScript engine with the environment-version parameter within the URL. See the table below for possible values. If the specified JavaScript engine is unavailable, an error will be returned.

If the environment-version parameter is omitted, the JavaScript engine set for the active version of server code or the default JavaScript engine for Kii Cloud is used.

Value Version Remarks
0 Node.js 0.10.X The default JavaScript engine. This value can be specified until October 31, 2017
6 Node.js 6.X The default JavaScript engine after October 31, 2017

Executing server code via the Kii Cloud SDK for Android

Here is an example of executing server code via the Android SDK.

  • // 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.
        }
      }
    });

Here is the brief explanation of the sample code:

  • Creates a KiiServerCodeEntry instance by executing the serverCodeEntry() method with the target endpoint (function) name. You can specify the version of the JavaScript engine for executing the server code with the KiiServerCodeEnvironmentVersion argument.
  • Prepares custom parameters (the username and password in this sample code) by setting them in a JSON Object and by creating a KiiServerCodeEntryArgument with the newArgument() method. Make sure to align the parameter keys with those in the server code so that the server code can properly get the parameter values (in this sample code the keys are "username" and "password").
  • Executes the server code by calling the execute() method with the custom parameters.
    • If there is a logged-in user, Kii Cloud interprets the server code as being executed by this user.
    • If there is no logged-in user, Kii Cloud interprets the server code as being executed by an anonymous user.
  • Gets the result by calling the getReturnedValue() method.
  • (Optionally) gets the number of the executed steps with the getExecutedSteps() method.
  • (Optionally) gets the version of Node.js with the getEnvironmentVersion() method.

The getReturnedValue() method will give you a JSON Object with the result stored in the "returnedValue" field (See Data types of return values for some examples). Use the appropriate method to fetch the actual result; for example, we fetch the newly-created username with getString() method in the sample code.

If your server code returns the value after the timeout, you can get the value with the getReturnedValue() method likewise. See Timeout for the format of the JSON object you can get with the method.

Executing server code via the Kii Cloud SDK for iOS

Here is an example of executing server code via the iOS SDK.

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];
    }];

Here is the brief explanation of the sample code:

  • Creates a KiiServerCodeEntry instance by executing the serverCodeEntry(_:) method with the target endpoint (function) name. You can specify the version of the JavaScript engine for executing the server code with the environmentVersion argument.
  • Prepares custom parameters (the username and password in this sample code) by setting them in an NSDictionary and by creating a KiiServerCodeEntryArgument with the KiiServerCodeEntryArgument(dictionary:) method. Make sure to align the parameter keys with those in the server code so that the server code can properly get the parameter values (in this sample code the keys are "username" and "password").
  • Executes the server code by calling the execute(_:) method with the custom parameters.
    • If there is a logged-in user, Kii Cloud interprets the server code as being executed by this user.
    • If there is no logged-in user, Kii Cloud interprets the server code as being executed by an anonymous user.
  • Gets the result by calling the returnedValue() method.
  • (Optionally) gets the number of the executed steps with the executedSteps() method.
  • (Optionally) gets the version of Node.js with the environmentVersion() method.

The returnedValue() method will give you an NSDictionary with the result stored in the "returnedValue" key (See Data types of return values for some examples). Use the appropriate method to fetch the actual result.

If your server code returns the value after the timeout, you can get the value with the returnedValue() method likewise. See Timeout for the format of the NSDictionary you can get with the method.

Executing server code via the Kii Cloud SDK for Unity

Here is an example of executing server code via the Unity SDK.

// 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;
});

Here is the brief explanation of the sample code:

  • Creates a KiiServerCodeEntry instance by executing the ServerCodeEntry() method with the target endpoint (function) name. You can specify the version of the JavaScript engine for executing the server code with the KiiServerCodeEnvironmentVersion argument.
  • Prepares custom parameters (the username and password in this sample code) by setting them in a JSON Object and by creating a KiiServerCodeEntryArgument with the NewArgument() method. Make sure to align the parameter keys with those in the server code so that the server code can properly get the parameter values (in this sample code the keys are "username" and "password").
  • Executes the server code by calling the Execute() method with the custom parameters.
    • If there is a logged-in user, Kii Cloud interprets the server code as being executed by this user.
    • If there is no logged-in user, Kii Cloud interprets the server code as being executed by an anonymous user.
  • Gets the result by the ReturnedValue property.
  • (Optionally) gets the number of the executed steps with the ExecutedSteps property.
  • (Optionally) gets the version of Node.js with the EnvironmentVersion property.

The ReturnedValue property will give you a JSON Object with the result stored in the "returnedValue" field (See Data types of return values for some examples). Use the appropriate method to fetch the actual result; for example, we fetch the newly-created username with GetString() method in the sample code.

If your server code returns the value after the timeout, you can get the value from the ReturnedValue property likewise. See Timeout for the format of the JSON object you can get with the method.

Executing server code via the Kii Cloud SDK for JavaScript

Here is an example of executing server code via the JavaScript SDK.

// 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.
    }
  }
);

Here is the brief explanation of the sample code:

  • Creates a KiiServerCodeEntry instance by executing the serverCodeEntry() method with the target endpoint (function) name. You can specify the version of the JavaScript engine for executing the server code with the environmentVersion argument.
  • Prepares custom parameters (the username and password in this sample code) by setting them in a JSON object. Make sure to align the parameter keys with those in the server code so that the server code can properly get the parameter values (in this sample code the keys are "username" and "password").
  • Executes the server code by calling the execute() method with the custom parameters.
    • If there is a logged-in user, Kii Cloud interprets the server code as being executed by this user.
    • If there is no logged-in user, Kii Cloud interprets the server code as being executed by an anonymous user.
  • Gets the result by calling the getReturnedValue() method.
  • (Optionally) gets the number of the executed steps with the getExecutedSteps() method.
  • (Optionally) gets the version of Node.js with the getEnvironmentVersion() method.

The getReturnedValue() method will give you a JSON Object with the result stored in the "returnedValue" field (See Data types of return values for some examples). Use the appropriate method to fetch the actual result; for example, we fetch the newly-created username in the sample code.

If your server code returns the value after the timeout, you can get the value with the getReturnedValue() method likewise. See Timeout for the format of the JSON object you can get with the method.

You cannot execute server code by manually executing another server code. If you attempt to do so, you will get an HTTP 409 response with the "OPERATION_NOT_ALLOWED" error.

Executing server code via Thing SDK Embedded

You can execute server code from the thing by using the Thing SDK Embedded. See Executing Server Code to learn how to execute server code.