AWS Lambda function handler in Go - AWS Lambda

AWS Lambda function handler in Go

The Lambda function handler is the method in your function code that processes events. When your function is invoked, Lambda runs the handler method. Your function runs until the handler returns a response, exits, or times out.

A Lambda function written in Go is authored as a Go executable. In your Lambda function code, you need to include the github.com/aws/aws-lambda-go/lambda package, which implements the Lambda programming model for Go. In addition, you need to implement handler function code and a main() function.

Example Go Lambda function
package main import ( "context" "fmt" "github.com/aws/aws-lambda-go/lambda" ) type MyEvent struct { Name string `json:"name"` } func HandleRequest(ctx context.Context, event *MyEvent) (*string, error) { if event == nil { return nil, fmt.Errorf("received nil event") } message := fmt.Sprintf("Hello %s!", event.Name) return &message, nil } func main() { lambda.Start(HandleRequest) }

Here is a sample input for this function:

{ "name": "Jane" }

Note the following:

  • package main: In Go, the package containing func main() must always be named main.

  • import: Use this to include the libraries your Lambda function requires. In this instance, it includes:

    • context: AWS Lambda context object in Go.

    • fmt: The Go Formatting object used to format the return value of your function.

    • github.com/aws/aws-lambda-go/lambda: As mentioned previously, implements the Lambda programming model for Go.

  • func HandleRequest(ctx context.Context, event *MyEvent) (*string, error): This is the signature of your Lambda handler. It's the entry point for your Lambda function and contains the logic that is executed when your function is invoked. In addition, the parameters included denote the following:

    • ctx context.Context: Provides runtime information for your Lambda function invocation. ctx is the variable you declare to leverage the information available via AWS Lambda context object in Go.

    • event *MyEvent: This is a parameter named event that points to MyEvent. It represents the input to the Lambda function.

    • *string, error: The handler returns two values. The first is a pointer to a string which contains the result of the Lambda function. The second is an error type, which is nil if there's no error and contains standard error information if something goes wrong. For more information on custom error handling, see AWS Lambda function errors in Go.

    • return &message, nil: Returns two values. The first is a pointer to a string message, which is a greeting constructed using the Name field from the input event. The second value, nil, indicates that the function didn't encounter any errors.

  • func main(): The entry point that runs your Lambda function code. This is required.

    By adding lambda.Start(HandleRequest) between func main(){} code brackets, your Lambda function will be executed. Per Go language standards, the opening bracket, { must be placed directly at the end of the main function signature.

Naming

provided.al2 and provided.al2023 runtimes

For Go functions that use the provided.al2 or provided.al2023 runtime in a .zip deployment package, the executable file that contains your function code must be named bootstrap. If you're deploying the function with a .zip file, the bootstrap file must be at the root of the .zip file. For Go functions that use the provided.al2 or provided.al2023 runtime in a container image, you can use any name for the executable file.

You can use any name for the handler. To reference the handler value in your code, you can use the _HANDLER environment variable.

go1.x runtime

For Go functions that use the go1.x runtime, the executable file and the handler can share any name. For example, if you set the value of the handler to Handler, Lambda will call the main() function in the Handler executable file.

To change the function handler name in the Lambda console, on the Runtime settings pane, choose Edit.

Lambda function handler using structured types

In the example above, the input type was a simple string. But you can also pass in structured events to your function handler:

package main import ( "fmt" "github.com/aws/aws-lambda-go/lambda" ) type MyEvent struct { Name string `json:"What is your name?"` Age int `json:"How old are you?"` } type MyResponse struct { Message string `json:"Answer"` } func HandleLambdaEvent(event *MyEvent) (*MyResponse, error) { if event == nil { return nil, fmt.Errorf("received nil event") } return &MyResponse{Message: fmt.Sprintf("%s is %d years old!", event.Name, event.Age)}, nil } func main() { lambda.Start(HandleLambdaEvent) }

Here is a sample input for this function:

{ "What is your name?": "Jim", "How old are you?": 33 }

The response looks like this:

{ "Answer": "Jim is 33 years old!" }

To be exported, field names in the event struct must be capitalized. For more information on handling events from AWS event sources, see aws-lambda-go/events.

Valid handler signatures

You have several options when building a Lambda function handler in Go, but you must adhere to the following rules:

  • The handler must be a function.

  • The handler may take between 0 and 2 arguments. If there are two arguments, the first argument must implement context.Context.

  • The handler may return between 0 and 2 arguments. If there is a single return value, it must implement error. If there are two return values, the second value must implement error. For more information on implementing error-handling information, see AWS Lambda function errors in Go.

The following lists valid handler signatures. TIn and TOut represent types compatible with the encoding/json standard library. For more information, see func Unmarshal to learn how these types are deserialized.

  • func ()
  • func () error
  • func (TIn) error
  • func () (TOut, error)
  • func (context.Context) error
  • func (context.Context, TIn) error
  • func (context.Context) (TOut, error)
  • func (context.Context, TIn) (TOut, error)

Using global state

You can declare and modify global variables that are independent of your Lambda function's handler code. In addition, your handler may declare an init function that is executed when your handler is loaded. This behaves the same in AWS Lambda as it does in standard Go programs. A single instance of your Lambda function will never handle multiple events simultaneously.

Example Go function with global variables
Note

This code uses the AWS SDK for Go V2. For more information, see Getting Started with the AWS SDK for Go V2.

package main import ( "context" "github.com/aws/aws-lambda-go/lambda" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" "log" ) var invokeCount int var myObjects []types.Object func init() { // Load the SDK configuration cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Fatalf("Unable to load SDK config: %v", err) } // Initialize an S3 client svc := s3.NewFromConfig(cfg) // Define the bucket name as a variable so we can take its address bucketName := "examplebucket" input := &s3.ListObjectsV2Input{ Bucket: &bucketName, } // List objects in the bucket result, err := svc.ListObjectsV2(context.TODO(), input) if err != nil { log.Fatalf("Failed to list objects: %v", err) } myObjects = result.Contents } func LambdaHandler(ctx context.Context) (int, error) { invokeCount++ for i, obj := range myObjects { log.Printf("object[%d] size: %d key: %s", i, obj.Size, *obj.Key) } return invokeCount, nil } func main() { lambda.Start(LambdaHandler) }