Define a Go handler function, compile it to a binary, and set the Handler parameter in the Function Compute console to the binary name. Function Compute runs this handler on each invocation.
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.
Quick start
Import the SDK package github.com/aliyun/fc-runtime-go-sdk/fc, implement a handler function, and pass it to fc.Start in main().
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)
}
This handler accepts a JSON event with a key field and returns a greeting string:
{
"key": "value"
}
Code walkthrough
| Element | Purpose |
|---|---|
package main |
Required entry package for any Go executable |
github.com/aliyun/fc-runtime-go-sdk/fc |
Function Compute Go SDK |
context |
Provides runtime context for the function invocation |
HandleRequest(ctx context.Context, event StructEvent) (string, error) |
Handler function: receives a context and a typed event, returns a string and an error |
fc.Start(HandleRequest) |
Registers the handler with Function Compute and starts the runtime loop |
Learn more about the Context object and Error handling.
Build and deploy
Initialize a Go module and install the Function Compute SDK:
go mod init my-fc-function
go get github.com/aliyun/fc-runtime-go-sdk
Compile your handler into a Linux binary (Function Compute runs on Linux):
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main main.go
Set the Handler parameter in the Function Compute console to main (the compiled binary name). Create an event function.
Handler signatures
Handler rules:
-
It must be a function.
-
It accepts 0 to 2 input parameters. If two parameters are used, the first must be
context.Context. -
It returns 0 to 2 values. A single return value must be of type
error. Two return values must haveerroras the second.
All valid signatures:
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)
InputType and OutputType must be encoding/json-compatible. Function Compute uses json.Unmarshal for input and json.Marshal for output. JSON Unmarshal.
Input event types
Choose an event type based on your use case:
| Event type | Use case | Example |
|---|---|---|
| Struct | Strongly typed events with known fields | event-struct.go |
string |
Raw string input | event-string.go |
map[string]interface{} |
Dynamic or loosely typed events | event-map.go |
Browse additional examples in fc-runtime-go-sdk/examples.
HTTP trigger handlers
To handle HTTP requests from an HTTP trigger or custom domain, use HTTPTriggerEvent and HTTPTriggerResponse from the SDK events package.
Handle HTTP trigger events
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)
}
This handler reads the request body from HTTPTriggerEvent, Base64-decodes it if needed, and echoes it back. The structs are from github.com/aliyun/fc-runtime-go-sdk/events. Use an HTTP trigger to invoke a function.
Invoke the function
Prerequisites
Make sure that you have:
-
A function created in a Go runtime with the preceding handler code
-
An HTTP trigger configured for the function
Procedure
-
Log on to the Function Compute console. In the left-side navigation pane, click Functions.
-
In the top navigation bar, select a region. On the Functions page, click the target function.
-
Click the Triggers tab. Copy the public endpoint of the HTTP trigger.
-
Send a request to the endpoint:
curl -i "https://http-trigger-demo.cn-shanghai.fcapp.run" -d "Hello FC!"
-
If Authentication Method is No Authentication, call the function directly with curl or Postman.
-
If set to Signature Authentication or JWT Authentication, include the required credentials. Authentication.
Troubleshoot Test Function errors
This handler expects HTTP trigger input. The Test Function button sends a standard event payload instead, producing a 400 error:
{
"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}"
}
To inspect the raw event regardless of source, use a []byte handler:
// GetRawRequestEvent returns the raw event as the response body
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)
}