Help Center> FunctionGraph> Developer Guide> Developing Functions> Developing Functions in Go 1.8.3

Developing Functions in Go 1.8.3

Function Syntax

You are advised to use Go 1.x.

Syntax for creating a handler function in Go:

func Handler (payload []byte, ctx context.RuntimeContext)

  • Handler: name of the function that FunctionGraph invokes to execute your code. The name must be consistent with that you define when creating a function, and must start with an uppercase letter.
  • payload: event parameter defined for the function. The parameter is in JSON format.
  • ctx: runtime information provided for executing the function. For details, see SDK APIs.

SDK APIs

  • Context APIs

    The Go SDK provides multiple context APIs and a logging API. The download link of the Go SDK is provided in Table 1. Table 1 describes the context APIs provided by FunctionGraph.

    Table 1 Context methods

    Method

    Description

    GetRequestID() string

    Obtains a request ID.

    GetRemainingTimeInMilliSeconds()

    Obtains the remaining running time of a function.

    GetAccessKey() string

    Obtains the AK (valid for 24 hours) of an agency. If you use this method, you need to configure an agency for the function.

    GetSecretKey() string

    Obtains the SK (valid for 24 hours) of an agency. If you use this method, you need to configure an agency for the function.

    GetUserData(key string) string

    Uses keys to obtain the values passed by environment variables.

    GetFunctionName() string

    Obtains the name of a function.

    GetRunningTimeInSeconds() int

    Obtains the timeout of a function.

    GetVersion() string

    Obtains the version of a function.

    GetMemorySize() int

    Obtains the allocated memory.

    GetCPUNumber() int

    Number of CPU millicores used by the function (1 core = 1000 millicores).

    The value of this field is proportional to that of MemorySize. By default, 100 CPU millicores are required for 128 MB memory. The number of CPU millicores is calculated as follows: Memory/128 x 100 + 200 (basic CPU millicores).

    GetProjectID() string

    Obtains a project ID.

    GetPackage() string

    Obtains a function group, that is, an app.

    GetToken() string

    Obtains the token (valid for 24 hours) of an agency. If you use this method, you need to configure an agency for the function.

    GetLogger() context.RuntimeLogger

    Obtains the logger method provided by the context. By default, information such as the time and request ID is output.

    Results returned by using the GetToken(), GetAccessKey(), and GetSecretKey() methods contain sensitive information. Exercise caution when using these methods.

  • Logging API

    Table 2 describes the logging API provided in the Go SDK.

    Table 2 Logging API

    Method

    Description

    RuntimeLogger()

    • Records user input logs by using the method Logf(format string, args ...interface{}).
    • This method outputs logs in the format of Time-Request ID-Output, for example, 2017-10-25T09:10:03.328Z 473d369d-101a-445e-a7a8-315cca788f86 test log output.

Developing a Go Function

  1. Create a Go project.

    1. Log in to a Linux server on which the Go 1.8.3 SDK and required running environment have been installed. (Currently, Ubuntu 14.04, Ubuntu 16.04, SUSE 11.3, SUSE 12.0, and SUSE 12.1 are supported.) Then create the /home/fssgo/src/go-runtime directory, and decompress the Go SDK under this directory. Specifically, run the following two commands:

      $ mkdir -p /home/fssgo/src/go-runtime

      $ unzip fss-go-sdk.zip -d /home/fssgo/src/go-runtime

    2. Create a function file under the /home/fssgo/src/go-runtime directory and implement the following interface:

      func Handler(payload []byte, ctx context.RuntimeContext) (interface{}, error)

      In this interface, payload is the body of a client request, and ctx is the runtime context object provided for executing a function. For more information about the methods, see the SDK APIs. The following uses test.go as an example.

      package main
      
      import (
          "fmt"
          "encoding/json"
          "go-runtime/go-api/context"
      )
      
      type Greeting struct {
          Name   string  `json:"name"`
      }
      
      // Handler function
      func Handler(payload []byte, ctx context.RuntimeContext) (interface{}, error) {
          logger := ctx.GetLogger()
      
          var greeting Greeting
          err := json.Unmarshal(payload, &greeting)
          if err != nil {
              return "", fmt.Errorf("invalid request payload")
          }
      
          logger.Logf("hello %s.", greeting.Name)
      
          logger.Logf("RequestId: %s", ctx.GetRequestID())
          logger.Logf("FunctionName: %s", ctx.GetFunctionName())
          logger.Logf("Version: %s", ctx.GetVersion())
          return fmt.Sprintf("hello %s", greeting.Name), nil
      }
      1. If the error parameter returned by a function is not nil, the function execution fails.
      2. If the error parameter returned by a function is nil, FunctionGraph supports only the following types of values:

        nil: The HTTP response body is empty.

        []byte: The content in this byte array is the body of an HTTP response.

        string: The content in this string is the body of an HTTP response.

        Other: FunctionGraph returns a value for JSON encoding, and uses the encoded object as the body of an HTTP response. The Content-Type header of the HTTP response is set to application/json.

  2. Compile and package the function code.

    After completing the function code, compile and package it as follows:

    1. Set environment variables GOROOT and GOPATH.

      $ export GOROOT=/usr/local/go (Assume that the Go SDK is installed under the /usr/local/go directory.)

      $ export PATH=$GOROOT/bin:$PATH

      $ export GOPATH=/home/fssgo

    2. Compile the function code.

      $ cd /home/fssgo/src/go-runtime

      $ go build --buildmode=plugin -o testplugin.so test.go

      After compilation, a file named testplugin.so is generated under the current directory.

    3. Package the file.

      $ zip fss_examples_go1.8.zip testplugin.so

      After the command is executed, a file named fss_examples_go1.8.zip is generated under the current directory.

  3. Create a function.

    Log in to the FunctionGraph console, create a Go function, and upload the fss_examples_go1.8.zip file, as shown in Figure 1.
    Figure 1 Uploading the code package

    If you edit code in Go, package the compiled file into a ZIP file, and ensure that the name of the dynamic library file is consistent with the handler plugin name. For example, if the name of the dynamic library file is testplugin.so, set the handler plugin name to testplugin.Handler. The handler must be consistent with that defined in Step 1.

  4. Test the function.

    1. Create a test event.

      On the function details page that is displayed, choose Select test event > Configure test event. Configure the test event information, as shown in Figure 2, and then click Save.

      Figure 2 Configuring a test event
    2. On the function details page, select the configured test event, and click Test.

  5. View the function execution result.

    The function execution result consists of three parts: function output (returned by callback), summary, and logs (output by using the console.log or getLogger() method), as shown in Figure 3.

    Figure 3 Execution result

Execution Result

The execution result consists of the function output, summary, and log output.

Table 3 Description of the execution result

Parameter

Successful Execution

Failed Execution

Function Output

The defined function output information is returned.

A JSON file that contains errorMessage and errorType is returned. The format is as follows:

{
    "errorMessage": "", 
    "errorType":"", 
}

errorMessage: Error message returned by the runtime.

errorType: Error type.

Summary

Request ID, Memory Configured, Execution Duration, Memory Used, and Billed Duration are displayed.

Request ID, Memory Configured, Execution Duration, Memory Used, and Billed Duration are displayed.

Log Output

Function logs are printed. A maximum of 4 KB logs can be displayed.

Error information is printed. A maximum of 4 KB logs can be displayed.

Example of the function output when a function fails to be executed:

{
    "errorMessage": "Function plugin 'plugin' not found(stat ${RUNTIME_CODE_ROOT}/plugin.so: no such file or directory)",
    "errorType": "FunctionLoadError"
}

Example of the log output when a function fails to be executed:

2020-07-27 15:20:53.292+08:00 Start invoke request '51a44941-577b-4e1f-b2f6-2f2c3ca2f5f7', version: latest
2020-07-27 15:20:53.292+08:00 51a44941-577b-4e1f-b2f6-2f2c3ca2f5f7 Function plugin 'plugin' not found(stat ${RUNTIME_CODE_ROOT}/plugin.so: no such file or directory)
2020-07-27 15:20:53.293+08:00 Finish invoke request '51a44941-577b-4e1f-b2f6-2f2c3ca2f5f7'(invoke Failed), duration: 1.447ms, billing duration: 100ms, memory used: 58.723MB