All Products
Search
Document Center

Function Compute:Handlers

Last Updated:Oct 25, 2024

You can use Go handlers to respond to received events and execute the corresponding business logic. This topic describes the concepts and structure of Go handlers and provides examples.

Note

If you want to use HTTP triggers or custom domain names to access functions, obtain request struct before you define HTTP responses. For more information, see Use an HTTP trigger to invoke a function.

What is a handler?

A handler of a function in Function Compute is the method that is used to process requests in function code. When a function is invoked, Function Compute uses the handler that you configure to process requests. You can configure a handler by specifying the Handler parameter in the Function Compute console.

A handler of a Go function in Function Compute is compiled into an executable binary file. You need to only set the handler of your function in Function Compute to the name of the executable file.

For more information about Function Compute functions and related operations, see Create an event function.

Configurations of handlers must conform to the configuration specifications of Function Compute. The configuration specifications vary based on the handler type.

Example:

In Go code, you need to introduce the official SDK library aliyun/serverless/fc-runtime-go-sdk/fc and implement the handler and main functions. The following sample code provides an example:

package main

import (
    "fmt"
    "context"

    "github.com/aliyun/fc-runtime-go-sdk/fc"
)

type StructEvent struct {
    Key string `json:"key"`
}

func HandleRequest(ctx context.Context, event StructEvent) (string, error) {
    return fmt.Sprintf("hello, %s!", event.Key), nil
}

func main() {
    fc.Start(HandleRequest)
}

The value of input event is a JSON string that contains the key property. The following sample code provides an example:

{
  "key": "value"
}

Parameter description:

  • package main: the main package. Each Go application contains a main package.

  • import: imports Function Compute dependencies. You need to import the following dependencies:

    • github.com/aliyun/fc-runtime-go-sdk/fc: the core library for Go in Function Compute

    • context: the Go context object in Function Compute.

  • func HandleRequest(ctx context.Context, event StructEvent) (string, error): the handler, which must contain the code to execute. The following items describe the parameters:

    • ctx context.Context: the runtime context information for your Function Compute function. For more information, see Context.

    • event StructEvent: data to be passed in when the function is invoked. Multiple data types are supported.

    • string, error: the return message, which contains a string and an error message. For more information, see Error handling.

    • return fmt.Sprintf("Hi,%s !", event.Key), nil: returns the hello information, which contains the input event. If nil is returned, no error occurs.

  • func main(): the entry point for running the code of the Function Compute function. Go programs must contain main functions. The fc.Start(HandleRequest) code allows your program to run on Alibaba Cloud Function Compute.

Event handler signatures

The following items list valid event handler signatures. Among them, InputType and OutputType are compatible with the encoding/json standard library.

Function Compute deserializes the input InputType by using the json.Unmarshal method and serializes the returned OutputType by using the json.Marshal method. For more information about how to deserialize the data returned by a function, see JSON Unmarshal.

  • func ()

  • func () error

  • func (InputType) error

  • func () (OutputType, error)

  • func (InputType) (OutputType, error)

  • func (context.Context) error

  • func (context.Context, InputType) error

  • func (context.Context) (OutputType, error)

  • func (context.Context, InputType) (OutputType, error)

You must use a handler based on the following rules:

  • The handler must be a function.

  • The handler can contain up to two input parameters. If the handler contains two input parameters, the first input parameter must be context.Context.

  • The handler can return up to two values. If only one value is returned, the value must indicate the error type. If two values are returned, the second value must indicate the error message.

The following section describes the sample code for handlers:

  • event-struct.go: the sample code for a handler whose event object is of the STRUCT type.

  • event-string.go: the sample code for a handler whose event object is of the STRING type.

  • event-map.go: the sample code for a handler whose event object is of the map[string]interface{} type.

For more information about the sample code for other handlers, see examples.

Context

For more information about how to use context, see Context.

Use an HTTP trigger to invoke a function

Sample code

package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/aliyun/fc-runtime-go-sdk/events"
	"github.com/aliyun/fc-runtime-go-sdk/fc"
)

type HTTPTriggerEvent events.HTTPTriggerEvent
type HTTPTriggerResponse events.HTTPTriggerResponse

func (h HTTPTriggerEvent) String() string {
	jsonBytes, err := json.MarshalIndent(h, "", "  ")
	if err != nil {
		return ""
	}
	return string(jsonBytes)
}

func NewHTTPTriggerResponse(statusCode int) *HTTPTriggerResponse {
	return &HTTPTriggerResponse{StatusCode: statusCode}
}

func (h *HTTPTriggerResponse) String() string {
	jsonBytes, err := json.MarshalIndent(h, "", "  ")
	if err != nil {
		return ""
	}
	return string(jsonBytes)
}

func (h *HTTPTriggerResponse) WithStatusCode(statusCode int) *HTTPTriggerResponse {
	h.StatusCode = statusCode
	return h
}

func (h *HTTPTriggerResponse) WithHeaders(headers map[string]string) *HTTPTriggerResponse {
	h.Headers = headers
	return h
}

func (h *HTTPTriggerResponse) WithIsBase64Encoded(isBase64Encoded bool) *HTTPTriggerResponse {
	h.IsBase64Encoded = isBase64Encoded
	return h
}

func (h *HTTPTriggerResponse) WithBody(body string) *HTTPTriggerResponse {
	h.Body = body
	return h
}

func HandleRequest(event HTTPTriggerEvent) (*HTTPTriggerResponse, error) {
	fmt.Printf("event: %v\n", event)
	if event.Body == nil {
		return NewHTTPTriggerResponse(http.StatusBadRequest).
			WithBody(fmt.Sprintf("the request did not come from an HTTP Trigger, event: %v", event)), nil
	}

	reqBody := *event.Body
	if event.IsBase64Encoded != nil && *event.IsBase64Encoded {
		decodedByte, err := base64.StdEncoding.DecodeString(*event.Body)
		if err != nil {
			return NewHTTPTriggerResponse(http.StatusBadRequest).
				WithBody(fmt.Sprintf("HTTP Trigger body is not base64 encoded, err: %v", err)), nil
		}
		reqBody = string(decodedByte)
	}
	return NewHTTPTriggerResponse(http.StatusOK).WithBody(reqBody), nil
}

func main() {
	fc.Start(HandleRequest)
}

The preceding example introduces the request structure HTTPTriggerEvent and response structure HTTPTriggerResponse of the HTTP trigger from the SDK. For more information about formats of request payloads and response payloads of HTTP triggers, see Use an HTTP trigger to invoke a function.

Before you start

Use the preceding example to create a function in a Go runtime and create an HTTP trigger. For more information, see Create an event function and Configure an HTTP trigger that invokes a function with HTTP requests.

Procedure

  1. Log on to the Function Compute console. In the left-side navigation pane, click Functions.

  2. In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.

  3. On the function details page, click the Configurations tab. In the left-side navigation pane, click Triggers. On the Triggers page, obtain the public endpoint of the HTTP trigger.

  4. Run the following command to invoke the function:

    curl -i "https://http-trigger-demo.cn-shanghai.fcapp.run" -d "Hello FC!"
    Important
    • If the Authentication Method parameter of the HTTP trigger is set to No Authentication, you can use Postman or curl to invoke the function. For more information, see Procedure.

    • If the Authentication Method parameter of the HTTP trigger is set to Signature Authentication or JWT Authentication, you can use the signature method or JWT authentication method to invoke the function. For more information, see Authentication.

Possible errors

This sample code can be called by using an HTTP trigger or a custom domain name. If you use an API operation but the configured test parameters do not comply with the request format requirements of HTTP triggers, an error is reported.

For example, the following error message is returned if you invoke the function by clicking Test Function in the Function Compute console after you configure the request parameters as "Hello, FC!".

{
    "statusCode": 400,
    "body": "the request did not come from an HTTP Trigger, event: {\n  \"version\": null,\n  \"rawPath\": null,\n  \"headers\": null,\n  \"queryParameters\": null,\n  \"body\": null,\n  \"isBase64Encoded\": null,\n  \"requestContext\": null\n}"
}

If you want to obtain the original request event payload, you can use the handler as shown in the following example.

// GetRawRequestEvent: obtain the raw request event
func GetRawRequestEvent(event []byte) (*HTTPTriggerResponse, error) {
	fmt.Printf("raw event: %s\n", string(event))
	return NewHTTPTriggerResponse(http.StatusOK).WithBody(string(event)), nil
}

func main() {
	fc.Start(GetRawRequestEvent)
}