diff --git a/README.md b/README.md index 3a610826..fc1356bb 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,9 @@ # AWS Lambda for Go -[![tests][1]][2] -[![Go Reference][5]][6] -[![GoCard][7]][8] -[![codecov][9]][10] - -[1]: https://github.com/aws/aws-lambda-go/workflows/tests/badge.svg -[2]: https://github.com/aws/aws-lambda-go/actions?query=workflow%3Atests -[5]: https://pkg.go.dev/badge/github.com/aws/aws-lambda-go.svg -[6]: https://pkg.go.dev/github.com/aws/aws-lambda-go -[7]: https://goreportcard.com/badge/github.com/aws/aws-lambda-go -[8]: https://goreportcard.com/report/github.com/aws/aws-lambda-go -[9]: https://codecov.io/gh/aws/aws-lambda-go/branch/master/graph/badge.svg -[10]: https://codecov.io/gh/aws/aws-lambda-go +[](https://github.com/aws/aws-lambda-go/actions?query=workflow%3Atests) +[](https://pkg.go.dev/github.com/aws/aws-lambda-go) +[](https://goreportcard.com/report/github.com/aws/aws-lambda-go) +[](https://codecov.io/gh/aws/aws-lambda-go) Libraries, samples, and tools to help Go developers develop AWS Lambda functions. @@ -108,5 +99,7 @@ To deploy your function, refer to the official documentation for [deploying usin # Event Integrations -The [event models](https://github.com/aws/aws-lambda-go/tree/master/events) can be used to model AWS event sources. The official documentation has [detailed walkthroughs](https://docs.aws.amazon.com/lambda/latest/dg/use-cases.html). +[](https://pkg.go.dev/github.com/aws/aws-lambda-go/events) + +The events package provides type definitions for common AWS event sources. The official documentation has [detailed walkthroughs](https://docs.aws.amazon.com/lambda/latest/dg/use-cases.html). diff --git a/cfn/README.md b/cfn/README.md deleted file mode 100644 index 86b03a85..00000000 --- a/cfn/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# Overview - -CloudFormation has a different way of responding to most events due to the way stacks execute. - -It is best to catch all errors and ensure the correct response is sent to the pre-signed URL that comes with the event. - -To make this easier, a wrapper exists to allow the creation of custom resources without having to handle that. - -# Sample Function - -This sample will safely 'Echo' back anything given into the Echo parameter within the Custom Resource call. - -```go - -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/cfn" - "github.com/aws/aws-lambda-go/lambda" -) - -func echoResource(ctx context.Context, event cfn.Event) (physicalResourceID string, data map[string]interface{}, err error) { - v, _ := event.ResourceProperties["Echo"].(string) - - data = map[string]interface{} { - "Echo": v, - } - - return -} - -func main() { - lambda.Start(cfn.LambdaWrap(echoResource)) -} -``` diff --git a/cfn/doc.go b/cfn/doc.go new file mode 100644 index 00000000..85c61e0f --- /dev/null +++ b/cfn/doc.go @@ -0,0 +1,11 @@ +// Package cfn provides helpers for implementing AWS CloudFormation custom resources. +// +// CloudFormation custom resources allow you to write custom provisioning logic that CloudFormation +// runs when you create, update, or delete stacks. This package handles the response protocol, +// making it easier to implement custom resource handlers. +// +// The LambdaWrap helper catches errors and ensures proper responses are sent to CloudFormation's +// pre-signed URL, preventing stack operations from hanging. +// +// See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html +package cfn diff --git a/cfn/example_test.go b/cfn/example_test.go new file mode 100644 index 00000000..c8d868c8 --- /dev/null +++ b/cfn/example_test.go @@ -0,0 +1,25 @@ +package cfn_test + +import ( + "context" + + "github.com/aws/aws-lambda-go/cfn" + "github.com/aws/aws-lambda-go/lambda" +) + +// CloudFormation custom resources require a different response handling due to the way stacks execute. +// The cfn.LambdaWrap helper catches all errors and ensures the correct response is sent to the +// pre-signed URL that comes with the event. +// +// This example safely 'Echo' back anything given into the Echo parameter within the Custom Resource call. +func Example() { + lambda.Start(cfn.LambdaWrap(func(ctx context.Context, event cfn.Event) (physicalResourceID string, data map[string]interface{}, err error) { + v, _ := event.ResourceProperties["Echo"].(string) + + data = map[string]interface{}{ + "Echo": v, + } + + return + })) +} diff --git a/events/README.md b/events/README.md deleted file mode 100644 index 234f2274..00000000 --- a/events/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# Overview - -[](https://pkg.go.dev/github.com/aws/aws-lambda-go/events) - -This package provides input types for Lambda functions that process AWS events. - -# Samples - -[ALB Target Group Events](README_ALBTargetGroupEvents.md) - -[API Gateway](README_ApiGatewayEvent.md) - -[API Gateway Custom Authorizer](README_ApiGatewayCustomAuthorizer.md) - -[AppSync](README_AppSync.md) - -[AutoScaling](README_AutoScaling.md) - -[ClientVPN Connection Handler](README_ClientVPN.md) - -[CloudFormation Events](../cfn/README.md) - -[CloudWatch Events](README_CloudWatch_Events.md) - -[CloudWatch Logs](README_CloudWatch_Logs.md) - -[Chime Bot Events](README_Chime_Bots.md) - -[CodeBuild Events](README_CodeBuild.md) - -[CodeCommit Events](README_CodeCommit.md) - -[CodeDeploy Events](README_CodeDeploy.md) - -[Cognito Events](README_Cognito.md) - -[Cognito Custom Authentication](README_Cognito_UserPools_CustomAuthLambdaTriggers.md) - -[Cognito PostConfirmation](README_Cognito_UserPools_PostConfirmation.md) - -[Cognito PreAuthentication](README_Cognito_UserPools_PreAuthentication.md) - -[Cognito PreSignup](README_Cognito_UserPools_PreSignup.md) - -[Cognito PreTokenGen](README_Cognito_UserPools_PreTokenGen.md) - -[Config Events](README_Config.md) - -[Connect Events](README_Connect.md) - -[DynamoDB Events](README_DynamoDB.md) - -[Kinesis Events](README_Kinesis.md) - -[Kinesis Data Analytics Events](README_KinesisDataAnalytics.md) - -[Kinesis Firehose Events](README_KinesisFirehose.md) - -[Lambda Events](README_Lambda.md) - -[Lex Events](README_Lex.md) - -[S3 Events](README_S3.md) - -[S3 Batch Job Events](README_S3_Batch_Job.md) - -[SES Events](README_SES.md) - -[SNS Events](README_SNS.md) - -[SQS Events](README_SQS.md) diff --git a/events/README_ALBTargetGroupEvents.md b/events/README_ALBTargetGroupEvents.md deleted file mode 100644 index e0a48210..00000000 --- a/events/README_ALBTargetGroupEvents.md +++ /dev/null @@ -1,38 +0,0 @@ -# Overview - -ALB Target Group events consist of a request that was routed to a Lambda function which is a registered target of an Application Load Balancer Target Group. When this happens, ALB expects the result of the function to be the response that ALB should respond with. - -https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html - -# Sample Function - -The following is a sample class and Lambda function that receives an ALB Target Group event as an input, writes some of the incoming data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go - -package main - -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -func handleRequest(ctx context.Context, request events.ALBTargetGroupRequest) (events.ALBTargetGroupResponse, error) { - fmt.Printf("Processing request data for traceId %s.\n", request.Headers["x-amzn-trace-id"]) - fmt.Printf("Body size = %d.\n", len(request.Body)) - - fmt.Println("Headers:") - for key, value := range request.Headers { - fmt.Printf(" %s: %s\n", key, value) - } - - return events.ALBTargetGroupResponse{Body: request.Body, StatusCode: 200, StatusDescription: "200 OK", IsBase64Encoded: false, Headers: map[string]string{}}, nil -} - -func main() { - lambda.Start(handleRequest) -} -``` diff --git a/events/README_ApiGatewayCustomAuthorizer.md b/events/README_ApiGatewayCustomAuthorizer.md deleted file mode 100644 index adb86078..00000000 --- a/events/README_ApiGatewayCustomAuthorizer.md +++ /dev/null @@ -1,67 +0,0 @@ -# Sample Function - -The following is a simple TOKEN authorizer example to demonstrate how to use an authorization -token to allow or deny a request. In this example, the caller named "user" is allowed to invoke -a request if the client-supplied token value is "allow". The caller is not allowed to invoke -the request if the token value is "deny". If the token value is "Unauthorized", the function -returns the "Unauthorized" error with an HTTP status code of 401. For any other token value, -the authorizer returns an "Invalid token" error. - -This example is based on the [JavaScript sample](https://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html#api-gateway-custom-authorizer-token-lambda-function-create) from the API Gateway documentation - -```go -package main - -import ( - "context" - "errors" - "strings" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -// Help function to generate an IAM policy -func generatePolicy(principalId, effect, resource string) events.APIGatewayCustomAuthorizerResponse { - authResponse := events.APIGatewayCustomAuthorizerResponse{PrincipalID: principalId} - - if effect != "" && resource != "" { - authResponse.PolicyDocument = events.APIGatewayCustomAuthorizerPolicy{ - Version: "2012-10-17", - Statement: []events.IAMPolicyStatement{ - { - Action: []string{"execute-api:Invoke"}, - Effect: effect, - Resource: []string{resource}, - }, - }, - } - } - - // Optional output with custom properties of the String, Number or Boolean type. - authResponse.Context = map[string]interface{}{ - "stringKey": "stringval", - "numberKey": 123, - "booleanKey": true, - } - return authResponse -} - -func handleRequest(ctx context.Context, event events.APIGatewayCustomAuthorizerRequest) (events.APIGatewayCustomAuthorizerResponse, error) { - token := event.AuthorizationToken - switch strings.ToLower(token) { - case "allow": - return generatePolicy("user", "Allow", event.MethodArn), nil - case "deny": - return generatePolicy("user", "Deny", event.MethodArn), nil - case "unauthorized": - return events.APIGatewayCustomAuthorizerResponse{}, errors.New("Unauthorized") // Return a 401 Unauthorized response - default: - return events.APIGatewayCustomAuthorizerResponse{}, errors.New("Error: Invalid token") - } -} - -func main() { - lambda.Start(handleRequest) -} -``` diff --git a/events/README_ApiGatewayEvent.md b/events/README_ApiGatewayEvent.md deleted file mode 100644 index 1faaf598..00000000 --- a/events/README_ApiGatewayEvent.md +++ /dev/null @@ -1,36 +0,0 @@ -# Overview - -API Gateway events consist of a request that was routed to a Lambda function by API Gateway. When this happens, API Gateway expects the result of the function to be the response that API Gateway should respond with. - -# Sample Function - -The following is a sample class and Lambda function that receives Amazon API Gateway event record data as an input, writes some of the record data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go - -package main - -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -func handleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { - fmt.Printf("Processing request data for request %s.\n", request.RequestContext.RequestID) - fmt.Printf("Body size = %d.\n", len(request.Body)) - - fmt.Println("Headers:") - for key, value := range request.Headers { - fmt.Printf(" %s: %s\n", key, value) - } - - return events.APIGatewayProxyResponse{Body: request.Body, StatusCode: 200}, nil -} - -func main() { - lambda.Start(handleRequest) -} -``` diff --git a/events/README_AutoScaling.md b/events/README_AutoScaling.md deleted file mode 100644 index 2835ada7..00000000 --- a/events/README_AutoScaling.md +++ /dev/null @@ -1,21 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives an Auto Scaling event as an input and logs the EC2 instance ID to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -func handler(ctx context.Context, autoScalingEvent events.AutoScalingEvent) { - fmt.Printf("Instance-Id available in event is %s \n", autoScalingEvent.Detail["EC2InstanceId"]) -} - -func main() { - lambda.Start(handler) -} -``` diff --git a/events/README_Chime_Bots.md b/events/README_Chime_Bots.md deleted file mode 100644 index d5d933d8..00000000 --- a/events/README_Chime_Bots.md +++ /dev/null @@ -1,67 +0,0 @@ -# Sample Function - -The following is a sample class and Lambda function that receives a Amazon Chime Bot event and handles the various event types accordingly. - -```go - -package main - -import ( - "fmt" - "context" - "net/http" - "bytes" - "encoding/json" - "errors" - "strconv" - - "github.com/aws/aws-lambda-go/events" -) - -func handler(_ context.Context, chimeBotEvent events.ChimeBotEvent) error { - switch chimeBotEvent.EventType { - case "Invite": - if err := message(chimeBotEvent.InboundHTTPSEndpoint.URL, "Thanks for inviting me to this room " + chimeBotEvent.Sender.SenderID); err != nil { - return fmt.Errorf("failed to send webhook message: %v", err) - } - return nil - case "Mention": - if err := message(chimeBotEvent.InboundHTTPSEndpoint.URL, "Thanks for mentioning me " + chimeBotEvent.Sender.SenderID); err != nil { - return fmt.Errorf("failed to send webhook message: %v", err) - } - return nil - case "Remove": - fmt.Printf("I have been removed from %q by %q", chimeBotEvent.Discussion.DiscussionType, chimeBotEvent.Sender.SenderID) - return nil - default: - return fmt.Errorf("event type %q is unsupported", chimeBotEvent.EventType) - } -} - -func message(url, content string) (error) { - input := &bytes.Buffer{} - if err := json.NewEncoder(input).Encode(webhookInput{Content:content}); err != nil { - return errors.New("failed to marshal request: " + err.Error()) - } - - resp, err := http.Post("POST", url, input) - if err != nil { - return errors.New("failed to execute post http request: " + err.Error()) - } - - if resp != nil && resp.Body != nil { - defer resp.Body.Close() - } - - if resp.StatusCode != http.StatusOK { - return errors.New("bad response: status code not is " + strconv.Itoa(http.StatusOK) + " not " + strconv.Itoa(resp.StatusCode)) - } - - return nil -} - -type webhookInput struct { - Content string `json:"Content"` -} - -``` diff --git a/events/README_ClientVPN.md b/events/README_ClientVPN.md deleted file mode 100644 index ab8c0e39..00000000 --- a/events/README_ClientVPN.md +++ /dev/null @@ -1,56 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives a Client VPN connection handler request as an input and then validates the IP address input and checks whether the connection source IP is on the allowed list defined as a map inside the function. If the source IP matches an allowed IP address it allows the access, otherwise an error message is presented to the user. Debug logs are generated to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go -import ( - "fmt" - "log" - "net" - - "encoding/json" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -var ( - AllowedIPs = map[string]bool{ - "10.11.12.13": true, - } -) - -func handler(request events.ClientVPNConnectionHandlerRequest) (events.ClientVPNConnectionHandlerResponse, error) { - requestJson, _ := json.MarshalIndent(request, "", " ") - log.Printf("REQUEST: %s", requestJson) - - sourceIP := request.PublicIP - if net.ParseIP(sourceIP) == nil { - return events.ClientVPNConnectionHandlerResponse{}, fmt.Errorf("Invalid parameter PublicIP passed in request: %q", sourceIP) - } - - log.Printf("SOURCE IP: %q", sourceIP) - - if allowed, ok := AllowedIPs[sourceIP]; ok && allowed { - log.Printf("Allowing access from: %q", sourceIP) - return events.ClientVPNConnectionHandlerResponse{ - Allow: true, - ErrorMsgOnFailedPostureCompliance: "", - PostureComplianceStatuses: []string{}, - SchemaVersion: "v1", - }, nil - } - - log.Printf("Blocking access from: %q", sourceIP) - return events.ClientVPNConnectionHandlerResponse{ - Allow: false, - ErrorMsgOnFailedPostureCompliance: "You're trying to connect from an IP address that is not allowed.", - PostureComplianceStatuses: []string{"BlockedSourceIP"}, - SchemaVersion: "v1", - }, nil -} - -func main() { - lambda.Start(handler) -} -``` diff --git a/events/README_CloudWatch_Logs.md b/events/README_CloudWatch_Logs.md deleted file mode 100644 index 75a219e0..00000000 --- a/events/README_CloudWatch_Logs.md +++ /dev/null @@ -1,20 +0,0 @@ - -# Sample Function - -The following is a Lambda function that receives Amazon CloudWatch Logs event record data as input and writes message part to Lambda's CloudWatch Logs. Note that by default anything written to Console will be logged as CloudWatch Logs events. - -```go -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" -) - -func handler(ctx context.Context, logsEvent events.CloudwatchLogsEvent) { - data, _ := logsEvent.AWSLogs.Parse() - for _, logEvent := range data.LogEvents { - fmt.Printf("Message = %s\n", logEvent.Message) - } -} -``` diff --git a/events/README_CodeBuild.md b/events/README_CodeBuild.md deleted file mode 100644 index 729eaa46..00000000 --- a/events/README_CodeBuild.md +++ /dev/null @@ -1,15 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives an Amazon CodeBuild event -and writes it to standard output. - -```go -import ( - "fmt" - "github.com/aws/aws-lambda-go/events" -) - -func handleRequest(evt events.CodeBuildEvent) { - fmt.Println(evt) -} -``` diff --git a/events/README_CodeCommit.md b/events/README_CodeCommit.md deleted file mode 100644 index aea1d703..00000000 --- a/events/README_CodeCommit.md +++ /dev/null @@ -1,17 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives Amazon CodeCommit event -records input and prints them to `os.Stdout`.) - -```go -import ( - "fmt" - "github.com/aws/aws-lambda-go/events" -) - -func handleRequest(evt events.CodeCommitEvent) { - for _, record := range evt.Records { - fmt.Println(record) - } -} -``` diff --git a/events/README_CodeDeploy.md b/events/README_CodeDeploy.md deleted file mode 100644 index 761c0b01..00000000 --- a/events/README_CodeDeploy.md +++ /dev/null @@ -1,15 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives an Amazon CodeDeploy event -and writes it to standard output. - -```go -import ( - "fmt" - "github.com/aws/aws-lambda-go/events" -) - -func handleRequest(evt events.CodeDeployEvent) { - fmt.Println(evt) -} -``` diff --git a/events/README_Cognito.md b/events/README_Cognito.md deleted file mode 100644 index 9a7249e8..00000000 --- a/events/README_Cognito.md +++ /dev/null @@ -1,32 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives Amazon Cognito Sync event record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go - -package main - -import ( - "fmt" - - "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-lambda-go/events" -) - -func handler(cognitoEvent events.CognitoEvent) error { - for datasetName, datasetRecord := range cognitoEvent.DatasetRecords { - fmt.Printf("[%s -- %s] %s -> %s -> %s \n", - cognitoEvent.EventType, - datasetName, - datasetRecord.OldValue, - datasetRecord.Op, - datasetRecord.NewValue) - } - return nil -} - -func main() { - lambda.Start(handler) -} - -``` diff --git a/events/README_Cognito_UserPools_CustomAuthLambdaTriggers.md b/events/README_Cognito_UserPools_CustomAuthLambdaTriggers.md deleted file mode 100644 index 737339cb..00000000 --- a/events/README_Cognito_UserPools_CustomAuthLambdaTriggers.md +++ /dev/null @@ -1,69 +0,0 @@ -# Sample Function - -The following is a sample Lambda functions that are used for custom authentication with Cognito User Pools. -These Lambda triggers issue and verify their own challenges as part of a user pool [custom authentication flow](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html#amazon-cognito-user-pools-custom-authentication-flow). - -Please see instructions for setting up the Cognito triggers at https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html - -Define Auth Challenge Lambda Trigger: -```go -package main - -import ( - "fmt" - - "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-lambda-go/events" -) - -func handler(event *events.CognitoEventUserPoolsDefineAuthChallenge) (*events.CognitoEventUserPoolsDefineAuthChallenge, error) { - fmt.Printf("Define Auth Challenge: %+v\n", event) - return event, nil -} - -func main() { - lambda.Start(handler) -} -``` - -Create Auth Challenge Lambda Trigger: -```go -package main - -import ( - "fmt" - - "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-lambda-go/events" -) - -func handler(event *events.CognitoEventUserPoolsCreateAuthChallenge) (*events.CognitoEventUserPoolsCreateAuthChallenge, error) { - fmt.Printf("Create Auth Challenge: %+v\n", event) - return event, nil -} - -func main() { - lambda.Start(handler) -} -``` - -Verify Auth Challenge Response Lambda Trigger: -```go -package main - -import ( - "fmt" - - "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-lambda-go/events" -) - -func handler(event *events.CognitoEventUserPoolsVerifyAuthChallenge) (*events.CognitoEventUserPoolsVerifyAuthChallenge, error) { - fmt.Printf("Verify Auth Challenge: %+v\n", event) - return event, nil -} - -func main() { - lambda.Start(handler) -} -``` diff --git a/events/README_Cognito_UserPools_PostConfirmation.md b/events/README_Cognito_UserPools_PostConfirmation.md deleted file mode 100644 index 0efab64f..00000000 --- a/events/README_Cognito_UserPools_PostConfirmation.md +++ /dev/null @@ -1,25 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives Amazon Cognito User Pools post-confirmation event as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -Please see instructions for setting up the Cognito triggers at https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html . - -```go -package main - -import ( - "fmt" - - "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-lambda-go/events" -) - -func handler(event events.CognitoEventUserPoolsPostConfirmation) (events.CognitoEventUserPoolsPostConfirmation, error) { - fmt.Printf("PostConfirmation for user: %s\n", event.UserName) - return event, nil -} - -func main() { - lambda.Start(handler) -} -``` diff --git a/events/README_Cognito_UserPools_PreAuthentication.md b/events/README_Cognito_UserPools_PreAuthentication.md deleted file mode 100644 index 0e74214f..00000000 --- a/events/README_Cognito_UserPools_PreAuthentication.md +++ /dev/null @@ -1,25 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives Amazon Cognito User Pools pre-authentication event as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -Please see instructions for setting up the Cognito triggers at https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html . - -```go -package main - -import ( - "fmt" - - "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-lambda-go/events" -) - -func handler(event events.CognitoEventUserPoolsPreAuthentication) (events.CognitoEventUserPoolsPreAuthentication, error) { - fmt.Printf("PreAuthentication of user: %s\n", event.UserName) - return event, nil -} - -func main() { - lambda.Start(handler) -} -``` diff --git a/events/README_Cognito_UserPools_PreSignup.md b/events/README_Cognito_UserPools_PreSignup.md deleted file mode 100644 index 0d48499e..00000000 --- a/events/README_Cognito_UserPools_PreSignup.md +++ /dev/null @@ -1,27 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives Amazon Cognito User Pools pre-signup event as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -Please see instructions for setting up the Cognito triggers at https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html . - -```go -package main - -import ( - "fmt" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -// handler is the lambda handler invoked by the `lambda.Start` function call -func handler(event events.CognitoEventUserPoolsPreSignup) (events.CognitoEventUserPoolsPreSignup, error) { - fmt.Printf("PreSignup of user: %s\n", event.UserName) - event.Response.AutoConfirmUser = true - return event, nil -} - -func main() { - lambda.Start(handler) -} -``` diff --git a/events/README_Cognito_UserPools_PreTokenGen.md b/events/README_Cognito_UserPools_PreTokenGen.md deleted file mode 100644 index f42cba02..00000000 --- a/events/README_Cognito_UserPools_PreTokenGen.md +++ /dev/null @@ -1,26 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives Amazon Cognito User Pools pre-token-gen event as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -Please see instructions for setting up the Cognito triggers at https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html . - -```go -package main - -import ( - "fmt" - - "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-lambda-go/events" -) - -func handler(event events.CognitoEventUserPoolsPreTokenGen) (events.CognitoEventUserPoolsPreTokenGen, error) { - fmt.Printf("PreTokenGen of user: %s\n", event.UserName) - event.Response.ClaimsOverrideDetails.ClaimsToSuppress = []string{"family_name"} - return event, nil -} - -func main() { - lambda.Start(handler) -} -``` diff --git a/events/README_Config.md b/events/README_Config.md deleted file mode 100644 index e8d08330..00000000 --- a/events/README_Config.md +++ /dev/null @@ -1,18 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives Amazon Config event record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go - -import ( - "strings" - "github.com/aws/aws-lambda-go/events" -) - -func handleRequest(ctx context.Context, configEvent events.ConfigEvent) { - fmt.Printf("AWS Config rule: %s\n", configEvent.ConfigRuleName) - fmt.Printf("Invoking event JSON: %s\n", configEvent.InvokingEvent) - fmt.Printf("Event version: %s\n", configEvent.Version) -} - -``` diff --git a/events/README_Connect.md b/events/README_Connect.md deleted file mode 100644 index 9e4c92b0..00000000 --- a/events/README_Connect.md +++ /dev/null @@ -1,35 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives an Amazon Connect event as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go -package main - -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -func main() { - lambda.Start(handler) -} - -func handler(ctx context.Context, connectEvent events.ConnectEvent) (events.ConnectResponse, error) { - fmt.Printf("Processing Connect event with ContactID %s.\n", connectEvent.Details.ContactData.ContactID) - - fmt.Printf("Invoked with %d parameters\n", len(connectEvent.Details.Parameters)) - for k, v := range connectEvent.Details.Parameters { - fmt.Printf("%s : %s\n", k, v) - } - - resp := events.ConnectResponse{ - "Result": "Success", - "NewAttribute": "NewValue", - } - - return resp, nil -} -``` diff --git a/events/README_DynamoDB.md b/events/README_DynamoDB.md deleted file mode 100644 index a01201ff..00000000 --- a/events/README_DynamoDB.md +++ /dev/null @@ -1,80 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that receives DynamoDB event data as input and writes some of the record data to CloudWatch Logs. (Note that by default anything written to Console will be logged as CloudWatch Logs.) - -```go -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" -) - -func handleRequest(ctx context.Context, e events.DynamoDBEvent) { - - for _, record := range e.Records { - fmt.Printf("Processing request data for event ID %s, type %s.\n", record.EventID, record.EventName) - - // Print new values for attributes of type String - for name, value := range record.Change.NewImage { - if value.DataType() == events.DataTypeString { - fmt.Printf("Attribute name: %s, value: %s\n", name, value.String()) - } - } - } -} -``` - -# Reading attribute values - -Stream notifications are delivered to the Lambda handler whenever data in the DynamoDB table is modified. -Depending on the Stream settings, a StreamRecord may contain the following data: - -* Keys: key attributes of the modified item. -* NewImage: the entire item, as it appears after it was modified. -* OldImage: the entire item, as it appeared before it was modified. - -The values for the attributes can be accessed using the AttributeValue type. For each type -supported natively by DynamoDB, there is a corresponding accessor method: - -DynamoDB type | AttributeValue accessor method | Return type | DataType constant ----------------|--------------------------------|---------------------------|------------------ -B (Binary) | Binary() | []byte | DataTypeBinary -BOOL (Boolean) | Boolean() | bool | DataTypeBoolean -BS (Binary Set)| BinarySet() | [][]byte | DataTypeBinarySet -L (List) | List() | []AttributeValue | DataTypeList -M (Map) | Map() | map[string]AttributeValue | DataTypeMap -N (Number) | Number() / Integer() / Float() | string / int64 / float64 | DataTypeNumber -NS (Number Set)| NumberSet() | []string | DataTypeNumberSet -NULL (Null) | IsNull() | bool | DataTypeNull -S (String) | String() | string | DataTypeString -SS (String Set)| StringSet() | []string | DataTypeStringSet - -Calling the accessor method for the incorrect type will result in a panic. If the type needs to -be discovered in runtime, the method DataType() can be used in order to determine the correct accessor. - -More information about DynamoDB data types can be seen [in this documentation](http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_AttributeValue.html). - -The following example reads values of attributes name and age, for which types are known to be String and Number: - -```go -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" -) - -func handleRequest(ctx context.Context, e events.DynamoDBEvent) { - - for _, record := range e.Records { - fmt.Printf("Processing request data for event ID %s, type %s.\n", record.EventID, record.EventName) - - // Print new values for attributes name and age - name := record.Change.NewImage["name"].String() - age, _ := record.Change.NewImage["age"].Integer() - - fmt.Printf("Name: %s, age: %d\n", name, age) - } -} -``` diff --git a/events/README_ECS_ContainerInstance.md b/events/README_ECS_ContainerInstance.md deleted file mode 100644 index 36d7e1b6..00000000 --- a/events/README_ECS_ContainerInstance.md +++ /dev/null @@ -1,26 +0,0 @@ -# Sample Function - -The following is a sample class and Lambda function that receives Amazon ECS Container instance state change events record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go - -package main - -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -func handler(ctx context.Context, ecsEvent events.ECSContainerInstanceEvent) { - outputJSON, _ := json.MarshalIndent(ecsEvent, "", " ") - fmt.Printf("Data = %s", outputJSON) -} - -func main() { - lambda.Start(handler) -} - -``` diff --git a/events/README_EventBridge_Events.md b/events/README_EventBridge_Events.md deleted file mode 100644 index 52ea90c2..00000000 --- a/events/README_EventBridge_Events.md +++ /dev/null @@ -1,38 +0,0 @@ - -# Sample Function - -The following is a Lambda function that receives Amazon EventBridge event record data as input and writes event detail to Lambda's CloudWatch Logs. Note that by default anything written to Console will be logged as CloudWatch Logs events. - -```go -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" -) - -func handler(ctx context.Context, event events.EventBridgeEvent) { - fmt.Printf("Detail = %s\n", event.Detail) -} -``` - -## CloudWatch Scheduled Events - -If you have a constant JSON text in a CloudWatch Scheduled Event, it can be accessed either by explicitly defining a structure for the json payload you would expect: - -```go -type MyRequest struct { - Name string `json:"name"` -} - -func handler(ctx context.Context, req MyRequest) { -} -``` - -or by accepting raw json blob as is: - -```go -func handler(ctx context.Context, b json.RawMessage) { - // json.RawMessage is basically []byte which can be unmarshalled -} -``` diff --git a/events/README_Kinesis.md b/events/README_Kinesis.md deleted file mode 100644 index 7133d4b5..00000000 --- a/events/README_Kinesis.md +++ /dev/null @@ -1,33 +0,0 @@ -# Sample Function - -The following is a sample class and Lambda function that receives Amazon Kinesis event record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go - -package main - -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -func handler(ctx context.Context, kinesisEvent events.KinesisEvent) error { - for _, record := range kinesisEvent.Records { - kinesisRecord := record.Kinesis - dataBytes := kinesisRecord.Data - dataText := string(dataBytes) - - fmt.Printf("%s Data = %s \n", record.EventName, dataText) - } - - return nil -} - -func main() { - lambda.Start(handler) -} - -``` diff --git a/events/README_KinesisDataAnalytics.md b/events/README_KinesisDataAnalytics.md deleted file mode 100644 index 6225294c..00000000 --- a/events/README_KinesisDataAnalytics.md +++ /dev/null @@ -1,45 +0,0 @@ -# Sample function - -The following is an example for an Application Destination Lambda function that receives Amazon Kinesis Data Analytics event records as an input. To send Kinesis Data Analytics output records the Lambda function must be compliant with the (required input and return data models)[https://docs.aws.amazon.com/kinesisanalytics/latest/dev/how-it-works-output-lambda.html], so the handler returns a list of delivery statuses for each record. - -The following Lambda function receives Amazon Kinesis Data Analytics event record data as an input and writes some of the record data to CloudWatch Logs. For each entry it adds an element to the response slice, marking it delivered. When the logic considers the delivery to be failed the `events.KinesisAnalyticsOutputDeliveryFailed` value should be used for the response `Result` field. - - -```go -package main - -import ( - "context" - "encoding/json" - "fmt" - "log" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -func handler(ctx context.Context, kinesisAnalyticsEvent events.KinesisAnalyticsOutputDeliveryEvent) (events.KinesisAnalyticsOutputDeliveryResponse, error) { - var err error - - var responses events.KinesisAnalyticsOutputDeliveryResponse - responses.Records = make([]events.KinesisAnalyticsOutputDeliveryResponseRecord, len(kinesisAnalyticsEvent.Records)) - - for i, record := range kinesisAnalyticsEvent.Records { - responses.Records[i] = events.KinesisAnalyticsOutputDeliveryResponseRecord{ - RecordID: record.RecordID, - Result: events.KinesisAnalyticsOutputDeliveryOK, - } - - dataBytes := record.Data - dataText := string(dataBytes) - - fmt.Printf("%s Data = %s \n", record.RecordID, dataText) - } - return responses, err -} - -func main() { - lambda.Start(handler) -} - -``` diff --git a/events/README_KinesisFirehose.md b/events/README_KinesisFirehose.md deleted file mode 100644 index ac7d85c4..00000000 --- a/events/README_KinesisFirehose.md +++ /dev/null @@ -1,45 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that transforms Kinesis Firehose records by doing a ToUpper on the data. - -```go - -package main - -import ( - "fmt" - "strings" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -func handleRequest(evnt events.KinesisFirehoseEvent) (events.KinesisFirehoseResponse, error) { - - fmt.Printf("InvocationID: %s\n", evnt.InvocationID) - fmt.Printf("DeliveryStreamArn: %s\n", evnt.DeliveryStreamArn) - fmt.Printf("Region: %s\n", evnt.Region) - - var response events.KinesisFirehoseResponse - - for _, record := range evnt.Records { - fmt.Printf("RecordID: %s\n", record.RecordID) - fmt.Printf("ApproximateArrivalTimestamp: %s\n", record.ApproximateArrivalTimestamp) - - // Transform data: ToUpper the data - var transformedRecord events.KinesisFirehoseResponseRecord - transformedRecord.RecordID = record.RecordID - transformedRecord.Result = events.KinesisFirehoseTransformedStateOk - transformedRecord.Data = []byte(strings.ToUpper(string(record.Data))) - - response.Records = append(response.Records, transformedRecord) - } - - return response, nil -} - -func main() { - lambda.Start(handleRequest) -} - -``` diff --git a/events/README_Lambda.md b/events/README_Lambda.md deleted file mode 100644 index 95aa75ec..00000000 --- a/events/README_Lambda.md +++ /dev/null @@ -1,35 +0,0 @@ -# Overview - -Lambda events consist of a request that was routed to a Lambda function by the Lambda Function URLs feature. When this happens, Lambda expects the result of the function to be the response that Lambda should respond with. - -# Sample Function - -The following is a sample class and Lambda function that receives Lambda Function URLs event record data as an input, writes some of the record data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go -package main - -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -func handleRequest(ctx context.Context, request events.LambdaFunctionURLRequest) (events.LambdaFunctionURLResponse, error) { - fmt.Printf("Processing request data for request %s.\n", request.RequestContext.RequestID) - fmt.Printf("Body size = %d.\n", len(request.Body)) - - fmt.Println("Headers:") - for key, value := range request.Headers { - fmt.Printf(" %s: %s\n", key, value) - } - - return events.LambdaFunctionURLResponse{Body: request.Body, StatusCode: 200}, nil -} - -func main() { - lambda.Start(handleRequest) -} -``` diff --git a/events/README_Lex.md b/events/README_Lex.md deleted file mode 100644 index 88d04e9a..00000000 --- a/events/README_Lex.md +++ /dev/null @@ -1,31 +0,0 @@ - -# Sample Function - -The following is a sample class and Lambda function that receives Amazon Lex event data as input, writes some of the record data to CloudWatch Logs, and responds back to Lex. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" -) - -func Handler(ctx context.Context, event events.LexEvent) (*lex.LexResponse, error) { - fmt.Printf("Received an input from Amazon Lex. Current Intent: %s", event.CurrentIntent.Name) - - messageContent := "Hello from AWS Lambda!" - - return &LexResponse{ - SessionAttributes: event.SessionAttributes, - DialogAction: events.LexDialogAction{ - Type: "Close", - Message: map[string]string{ - "content": messageContent, - "contentType": "PlainText", - }, - FulfillmentState: "Fulfilled", - }, - }, nil -} -``` diff --git a/events/README_S3.md b/events/README_S3.md deleted file mode 100644 index ac36ab0d..00000000 --- a/events/README_S3.md +++ /dev/null @@ -1,30 +0,0 @@ -# Sample Function - -The following is a sample class and Lambda function that receives Amazon S3 event record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go - -// main.go -package main - -import ( - "fmt" - "context" - "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-lambda-go/events" -) - -func handler(ctx context.Context, s3Event events.S3Event) { - for _, record := range s3Event.Records { - s3 := record.S3 - fmt.Printf("[%s - %s] Bucket = %s, Key = %s \n", record.EventSource, record.EventTime, s3.Bucket.Name, s3.Object.Key) - } -} - - -func main() { - // Make the handler available for Remote Procedure Call by AWS Lambda - lambda.Start(handler) -} - -``` diff --git a/events/README_S3_Batch_Job.md b/events/README_S3_Batch_Job.md deleted file mode 100644 index 19e4549d..00000000 --- a/events/README_S3_Batch_Job.md +++ /dev/null @@ -1,39 +0,0 @@ -# Sample Function - -The following is a sample class and Lambda function that receives Amazon S3 event record data as an input and writes some of the record data to CloudWatch Logs. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go - -import ( - "fmt" - "context" - "github.com/aws/aws-lambda-go/events" -) - -func handler(ctx context.Context, e events.S3BatchJobEvent) (response events.S3BatchJobResponse, err error) { - fmt.Printf("InvocationSchemaVersion: %s\n", e.InvocationSchemaVersion) - fmt.Printf("InvocationID: %s\n", e.InvocationID) - fmt.Printf("Job.ID: %s\n", e.Job.ID) - - for _, task := range e.Tasks { - fmt.Printf("TaskID: %s\n", task.TaskID) - fmt.Printf("S3Key: %s\n", task.S3Key) - fmt.Printf("S3VersionID: %s\n", task.S3VersionID) - fmt.Printf("S3BucketARN: %s\n", task.S3BucketARN) - - } - - fmt.Printf("InvocationSchemaVersion: %s\n", response.InvocationSchemaVersion) - fmt.Printf("TreatMissingKeysAs: %s\n", response.TreatMissingKeysAs) - fmt.Printf("InvocationID: %s\n", response.InvocationID) - - for _, result := range response.Results { - fmt.Printf("TaskID: %s\n", result.TaskID) - fmt.Printf("ResultCode: %s\n", result.ResultCode) - fmt.Printf("ResultString: %s\n", result.ResultString) - } - - return -} - -``` diff --git a/events/README_S3_Object_Lambda.md b/events/README_S3_Object_Lambda.md deleted file mode 100644 index f9ae1a73..00000000 --- a/events/README_S3_Object_Lambda.md +++ /dev/null @@ -1,83 +0,0 @@ -# Sample Function - -The following is a sample class and Lambda function that receives Amazon S3 Object Lambda event record data as an input and returns an object metadata output. - -```go - -// main.go -package main - -import ( - "context" - "crypto/md5" - "encoding/hex" - "encoding/json" - "io/ioutil" - "net/http" - "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/service/s3" -) - -func handler(ctx context.Context, event events.S3ObjectLambdaEvent) error { - url := event.GetObjectContext.InputS3URL - resp, err := http.Get(url) - if err != nil { - return err - } - defer resp.Body.Close() - bodyBytes, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - transformedObject := TransformedObject{ - Metadata: Metadata{ - Length: len(bodyBytes), - Md5: toMd5(bodyBytes), - }, - } - jsonData, err := json.Marshal(transformedObject) - if err != nil { - return err - } - cfg, err := config.LoadDefaultConfig(context.TODO()) - if err != nil { - return err - } - svc := s3.NewFromConfig(cfg) - input := &s3.WriteGetObjectResponseInput{ - RequestRoute: &event.GetObjectContext.OutputRoute, - RequestToken: &event.GetObjectContext.OutputToken, - Body: strings.NewReader(string(jsonData)), - } - res, err := svc.WriteGetObjectResponse(ctx, input) - if err != nil { - return err - } - fmt.Printf("%v", res) - return nil -} - -func toMd5(data []byte) string { - hasher := md5.New() - hasher.Write(data) - hash := hasher.Sum(nil) - - return hex.EncodeToString(hash) -} - -type TransformedObject struct { - Metadata Metadata `json:"metadata"` -} - -type Metadata struct { - Length int `json:"length"` - Md5 string `json:"md5"` -} - -func main() { - lambda.Start(handler) -} - -``` diff --git a/events/README_SES.md b/events/README_SES.md deleted file mode 100644 index dd471184..00000000 --- a/events/README_SES.md +++ /dev/null @@ -1,30 +0,0 @@ - -# Sample Function - -The following is a sample class and Lambda function that receives Amazon SES event message data as input, writes some of the message data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go -package main - -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -func handler(ctx context.Context, sesEvent events.SimpleEmailEvent) error { - for _, record := range sesEvent.Records { - ses := record.SES - fmt.Printf("[%s - %s] Mail = %+v, Receipt = %+v \n", record.EventVersion, record.EventSource, ses.Mail, ses.Receipt) - } - - return nil -} - -func main() { - lambda.Start(handler) -} - -``` diff --git a/events/README_SNS.md b/events/README_SNS.md deleted file mode 100644 index 924250c8..00000000 --- a/events/README_SNS.md +++ /dev/null @@ -1,21 +0,0 @@ - -# Sample Function - -The following is a sample class and Lambda function that receives Amazon SNS event record data as input, writes some of the record data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" -) - -func handler(ctx context.Context, snsEvent events.SNSEvent) { - for _, record := range snsEvent.Records { - snsRecord := record.SNS - - fmt.Printf("[%s %s] Message = %s \n", record.EventSource, snsRecord.Timestamp, snsRecord.Message) - } -} -``` diff --git a/events/README_SQS.md b/events/README_SQS.md deleted file mode 100644 index d852b16e..00000000 --- a/events/README_SQS.md +++ /dev/null @@ -1,29 +0,0 @@ - -# Sample Function - -The following is a sample class and Lambda function that receives Amazon SQS event message data as input, writes some of the message data to CloudWatch Logs, and responds with a 200 status and the same body as the request. (Note that anything written to stdout or stderr will be logged as CloudWatch Logs events.) - -```go -package main - -import ( - "context" - "fmt" - - "github.com/aws/aws-lambda-go/events" - "github.com/aws/aws-lambda-go/lambda" -) - -func handler(ctx context.Context, sqsEvent events.SQSEvent) error { - for _, message := range sqsEvent.Records { - fmt.Printf("The message %s for event source %s = %s \n", message.MessageId, message.EventSource, message.Body) - } - - return nil -} - -func main() { - lambda.Start(handler) -} - -``` diff --git a/events/README_SecretsManager_SecretRotationEvent.md b/events/README_SecretsManager_SecretRotationEvent.md deleted file mode 100644 index da085891..00000000 --- a/events/README_SecretsManager_SecretRotationEvent.md +++ /dev/null @@ -1,38 +0,0 @@ -# Sample Function - -The following is a sample Lambda function that handles a SecretsManager secret rotation event. - -```go -package main - -import ( - "fmt" - "context" - - "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-lambda-go/events" -) - -func handler(ctx context.Context, event events.SecretsManagerSecretRotationEvent) error { - fmt.Printf("rotating secret %s with token %s\n", - event.SecretID, event.ClientRequestToken) - - switch event.Step { - case "createSecret": - // create - case "setSecret": - // set - case "finishSecret": - // finish - case "testSecret": - // test - } - - return nil -} - - -func main() { - lambda.Start(handler) -} -``` diff --git a/events/doc.go b/events/doc.go new file mode 100644 index 00000000..e5c0b99e --- /dev/null +++ b/events/doc.go @@ -0,0 +1,8 @@ +// Package events provides type definitions for common AWS Lambda event sources. +// +// This package contains Go structs for events from services like API Gateway, S3, SQS, DynamoDB, +// and many others. These types can be used as input parameters to Lambda handler functions, +// allowing automatic JSON deserialization of incoming events. +// +// See https://docs.aws.amazon.com/lambda/latest/dg/lambda-services.html +package events diff --git a/events/example_alb_test.go b/events/example_alb_test.go new file mode 100644 index 00000000..6acf38c8 --- /dev/null +++ b/events/example_alb_test.go @@ -0,0 +1,26 @@ +package events_test + +import ( + "context" + "fmt" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +// ALB Target Group events consist of a request that was routed to a Lambda function +// which is a registered target of an Application Load Balancer Target Group. +// When this happens, ALB expects the result of the function to be the response that ALB should respond with. +func ExampleALBTargetGroupRequest() { + lambda.Start(func(ctx context.Context, request *events.ALBTargetGroupRequest) (*events.ALBTargetGroupResponse, error) { + fmt.Printf("Processing request data for traceId %s.\n", request.Headers["x-amzn-trace-id"]) + fmt.Printf("Body size = %d.\n", len(request.Body)) + + fmt.Println("Headers:") + for key, value := range request.Headers { + fmt.Printf(" %s: %s\n", key, value) + } + + return &events.ALBTargetGroupResponse{Body: request.Body, StatusCode: 200, StatusDescription: "200 OK", IsBase64Encoded: false, Headers: map[string]string{}}, nil + }) +} diff --git a/events/example_apigateway_custom_authorizer_test.go b/events/example_apigateway_custom_authorizer_test.go new file mode 100644 index 00000000..3de43739 --- /dev/null +++ b/events/example_apigateway_custom_authorizer_test.go @@ -0,0 +1,56 @@ +package events_test + +import ( + "context" + "errors" + "strings" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +// This is a simple TOKEN authorizer example to demonstrate how to use an authorization +// token to allow or deny a request. In this example, the caller named "user" is allowed to invoke +// a request if the client-supplied token value is "allow". The caller is not allowed to invoke +// the request if the token value is "deny". If the token value is "Unauthorized", the function +// returns the "Unauthorized" error with an HTTP status code of 401. For any other token value, +// the authorizer returns an "Invalid token" error. +func ExampleAPIGatewayCustomAuthorizerRequest() { + lambda.Start(func(ctx context.Context, event *events.APIGatewayCustomAuthorizerRequest) (*events.APIGatewayCustomAuthorizerResponse, error) { + token := event.AuthorizationToken + switch strings.ToLower(token) { + case "allow": + return generatePolicy("user", "Allow", event.MethodArn), nil + case "deny": + return generatePolicy("user", "Deny", event.MethodArn), nil + case "unauthorized": + return nil, errors.New("Unauthorized") + default: + return nil, errors.New("Error: Invalid token") + } + }) +} + +func generatePolicy(principalID, effect, resource string) *events.APIGatewayCustomAuthorizerResponse { + authResponse := &events.APIGatewayCustomAuthorizerResponse{PrincipalID: principalID} + + if effect != "" && resource != "" { + authResponse.PolicyDocument = events.APIGatewayCustomAuthorizerPolicy{ + Version: "2012-10-17", + Statement: []events.IAMPolicyStatement{ + { + Action: []string{"execute-api:Invoke"}, + Effect: effect, + Resource: []string{resource}, + }, + }, + } + } + + authResponse.Context = map[string]interface{}{ + "stringKey": "stringval", + "numberKey": 123, + "booleanKey": true, + } + return authResponse +} diff --git a/events/example_apigateway_test.go b/events/example_apigateway_test.go new file mode 100644 index 00000000..08a801e8 --- /dev/null +++ b/events/example_apigateway_test.go @@ -0,0 +1,25 @@ +package events_test + +import ( + "context" + "fmt" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +// API Gateway events consist of a request that was routed to a Lambda function by API Gateway. +// When this happens, API Gateway expects the result of the function to be the response that API Gateway should respond with. +func ExampleAPIGatewayProxyRequest() { + lambda.Start(func(ctx context.Context, request *events.APIGatewayProxyRequest) (*events.APIGatewayProxyResponse, error) { + fmt.Printf("Processing request data for request %s.\n", request.RequestContext.RequestID) + fmt.Printf("Body size = %d.\n", len(request.Body)) + + fmt.Println("Headers:") + for key, value := range request.Headers { + fmt.Printf(" %s: %s\n", key, value) + } + + return &events.APIGatewayProxyResponse{Body: request.Body, StatusCode: 200}, nil + }) +} diff --git a/events/example_chime_test.go b/events/example_chime_test.go new file mode 100644 index 00000000..4c9b1bae --- /dev/null +++ b/events/example_chime_test.go @@ -0,0 +1,27 @@ +package events_test + +import ( + "context" + "fmt" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +func ExampleChimeBotEvent() { + lambda.Start(func(_ context.Context, chimeBotEvent *events.ChimeBotEvent) error { + switch chimeBotEvent.EventType { + case "Invite": + fmt.Printf("Thanks for inviting me to this room %s\n", chimeBotEvent.Sender.SenderID) + return nil + case "Mention": + fmt.Printf("Thanks for mentioning me %s\n", chimeBotEvent.Sender.SenderID) + return nil + case "Remove": + fmt.Printf("I have been removed from %q by %q\n", chimeBotEvent.Discussion.DiscussionType, chimeBotEvent.Sender.SenderID) + return nil + default: + return fmt.Errorf("event type %q is unsupported", chimeBotEvent.EventType) + } + }) +} diff --git a/events/example_cognito_test.go b/events/example_cognito_test.go new file mode 100644 index 00000000..b7e267f7 --- /dev/null +++ b/events/example_cognito_test.go @@ -0,0 +1,64 @@ +package events_test + +import ( + "fmt" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +func ExampleCognitoEvent() { + lambda.Start(func(cognitoEvent *events.CognitoEvent) error { + for datasetName, datasetRecord := range cognitoEvent.DatasetRecords { + fmt.Printf("[%s -- %s] %s -> %s -> %s \n", + cognitoEvent.EventType, + datasetName, + datasetRecord.OldValue, + datasetRecord.Op, + datasetRecord.NewValue) + } + return nil + }) +} + +// For setting up Cognito User Pools triggers, see: +// https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html +func ExampleCognitoEventUserPoolsPreSignup() { + lambda.Start(func(event *events.CognitoEventUserPoolsPreSignup) (*events.CognitoEventUserPoolsPreSignup, error) { + fmt.Printf("PreSignup of user: %s\n", event.UserName) + event.Response.AutoConfirmUser = true + return event, nil + }) +} + +func ExampleCognitoEventUserPoolsPostConfirmation() { + lambda.Start(func(event *events.CognitoEventUserPoolsPostConfirmation) (*events.CognitoEventUserPoolsPostConfirmation, error) { + fmt.Printf("PostConfirmation for user: %s\n", event.UserName) + return event, nil + }) +} + +func ExampleCognitoEventUserPoolsPreAuthentication() { + lambda.Start(func(event *events.CognitoEventUserPoolsPreAuthentication) (*events.CognitoEventUserPoolsPreAuthentication, error) { + fmt.Printf("PreAuthentication of user: %s\n", event.UserName) + return event, nil + }) +} + +func ExampleCognitoEventUserPoolsPreTokenGen() { + lambda.Start(func(event *events.CognitoEventUserPoolsPreTokenGen) (*events.CognitoEventUserPoolsPreTokenGen, error) { + fmt.Printf("PreTokenGen of user: %s\n", event.UserName) + event.Response.ClaimsOverrideDetails.ClaimsToSuppress = []string{"family_name"} + return event, nil + }) +} + +// These Lambda triggers issue and verify their own challenges as part of a user pool custom authentication flow. +// For setting up custom authentication, see: +// https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html +func ExampleCognitoEventUserPoolsDefineAuthChallenge() { + lambda.Start(func(event *events.CognitoEventUserPoolsDefineAuthChallenge) (*events.CognitoEventUserPoolsDefineAuthChallenge, error) { + fmt.Printf("Define Auth Challenge: %+v\n", event) + return event, nil + }) +} diff --git a/events/example_connect_test.go b/events/example_connect_test.go new file mode 100644 index 00000000..2177bb97 --- /dev/null +++ b/events/example_connect_test.go @@ -0,0 +1,27 @@ +package events_test + +import ( + "context" + "fmt" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +func ExampleConnectEvent() { + lambda.Start(func(ctx context.Context, connectEvent *events.ConnectEvent) (*events.ConnectResponse, error) { + fmt.Printf("Processing Connect event with ContactID %s.\n", connectEvent.Details.ContactData.ContactID) + + fmt.Printf("Invoked with %d parameters\n", len(connectEvent.Details.Parameters)) + for k, v := range connectEvent.Details.Parameters { + fmt.Printf("%s : %s\n", k, v) + } + + resp := &events.ConnectResponse{ + "Result": "Success", + "NewAttribute": "NewValue", + } + + return resp, nil + }) +} diff --git a/events/example_dynamodb_test.go b/events/example_dynamodb_test.go new file mode 100644 index 00000000..1151bba9 --- /dev/null +++ b/events/example_dynamodb_test.go @@ -0,0 +1,28 @@ +package events_test + +import ( + "context" + "fmt" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +// Stream notifications are delivered to the Lambda handler whenever data in the DynamoDB table is modified. +// Depending on the Stream settings, a StreamRecord may contain: +// - Keys: key attributes of the modified item +// - NewImage: the entire item, as it appears after it was modified +// - OldImage: the entire item, as it appeared before it was modified +func ExampleDynamoDBEvent() { + lambda.Start(func(ctx context.Context, e *events.DynamoDBEvent) { + for _, record := range e.Records { + fmt.Printf("Processing request data for event ID %s, type %s.\n", record.EventID, record.EventName) + + for name, value := range record.Change.NewImage { + if value.DataType() == events.DataTypeString { + fmt.Printf("Attribute name: %s, value: %s\n", name, value.String()) + } + } + } + }) +} diff --git a/events/example_ecs_test.go b/events/example_ecs_test.go new file mode 100644 index 00000000..0bc78e27 --- /dev/null +++ b/events/example_ecs_test.go @@ -0,0 +1,17 @@ +package events_test + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +func ExampleECSContainerInstanceEvent() { + lambda.Start(func(ctx context.Context, ecsEvent *events.ECSContainerInstanceEvent) { + outputJSON, _ := json.MarshalIndent(ecsEvent, "", " ") + fmt.Printf("Data = %s", outputJSON) + }) +} diff --git a/events/example_kinesis_test.go b/events/example_kinesis_test.go new file mode 100644 index 00000000..3deb265d --- /dev/null +++ b/events/example_kinesis_test.go @@ -0,0 +1,69 @@ +package events_test + +import ( + "context" + "fmt" + "strings" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +func ExampleKinesisEvent() { + lambda.Start(func(ctx context.Context, kinesisEvent *events.KinesisEvent) error { + for _, record := range kinesisEvent.Records { + kinesisRecord := record.Kinesis + dataBytes := kinesisRecord.Data + dataText := string(dataBytes) + + fmt.Printf("%s Data = %s \n", record.EventName, dataText) + } + + return nil + }) +} + +// This example transforms Kinesis Firehose records by converting the data to uppercase. +func ExampleKinesisFirehoseEvent() { + lambda.Start(func(evnt *events.KinesisFirehoseEvent) (*events.KinesisFirehoseResponse, error) { + fmt.Printf("InvocationID: %s\n", evnt.InvocationID) + fmt.Printf("DeliveryStreamArn: %s\n", evnt.DeliveryStreamArn) + fmt.Printf("Region: %s\n", evnt.Region) + + response := &events.KinesisFirehoseResponse{} + + for _, record := range evnt.Records { + fmt.Printf("RecordID: %s\n", record.RecordID) + fmt.Printf("ApproximateArrivalTimestamp: %s\n", record.ApproximateArrivalTimestamp) + + var transformedRecord events.KinesisFirehoseResponseRecord + transformedRecord.RecordID = record.RecordID + transformedRecord.Result = events.KinesisFirehoseTransformedStateOk + transformedRecord.Data = []byte(strings.ToUpper(string(record.Data))) + + response.Records = append(response.Records, transformedRecord) + } + + return response, nil + }) +} + +func ExampleKinesisAnalyticsOutputDeliveryEvent() { + lambda.Start(func(ctx context.Context, kinesisAnalyticsEvent *events.KinesisAnalyticsOutputDeliveryEvent) (*events.KinesisAnalyticsOutputDeliveryResponse, error) { + responses := &events.KinesisAnalyticsOutputDeliveryResponse{} + responses.Records = make([]events.KinesisAnalyticsOutputDeliveryResponseRecord, len(kinesisAnalyticsEvent.Records)) + + for i, record := range kinesisAnalyticsEvent.Records { + responses.Records[i] = events.KinesisAnalyticsOutputDeliveryResponseRecord{ + RecordID: record.RecordID, + Result: events.KinesisAnalyticsOutputDeliveryOK, + } + + dataBytes := record.Data + dataText := string(dataBytes) + + fmt.Printf("%s Data = %s \n", record.RecordID, dataText) + } + return responses, nil + }) +} diff --git a/events/example_lambda_function_url_test.go b/events/example_lambda_function_url_test.go new file mode 100644 index 00000000..9f0be161 --- /dev/null +++ b/events/example_lambda_function_url_test.go @@ -0,0 +1,23 @@ +package events_test + +import ( + "context" + "fmt" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +func ExampleLambdaFunctionURLRequest() { + lambda.Start(func(ctx context.Context, request *events.LambdaFunctionURLRequest) (*events.LambdaFunctionURLResponse, error) { + fmt.Printf("Processing request data for request %s.\n", request.RequestContext.RequestID) + fmt.Printf("Body size = %d.\n", len(request.Body)) + + fmt.Println("Headers:") + for key, value := range request.Headers { + fmt.Printf(" %s: %s\n", key, value) + } + + return &events.LambdaFunctionURLResponse{Body: request.Body, StatusCode: 200}, nil + }) +} diff --git a/events/example_s3_test.go b/events/example_s3_test.go new file mode 100644 index 00000000..d64f6a94 --- /dev/null +++ b/events/example_s3_test.go @@ -0,0 +1,92 @@ +package events_test + +import ( + "context" + "crypto/md5" + "encoding/hex" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +func ExampleS3Event() { + lambda.Start(func(ctx context.Context, s3Event *events.S3Event) { + for _, record := range s3Event.Records { + s3 := record.S3 + fmt.Printf("[%s - %s] Bucket = %s, Key = %s \n", record.EventSource, record.EventTime, s3.Bucket.Name, s3.Object.Key) + } + }) +} + +// S3 Object Lambda allows you to add your own code to S3 GET requests to modify and process data +// as it is returned to an application. This example receives S3 Object Lambda event data and returns object metadata. +func ExampleS3ObjectLambdaEvent() { + lambda.Start(func(ctx context.Context, event *events.S3ObjectLambdaEvent) error { + url := event.GetObjectContext.InputS3URL + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + bodyBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + type Metadata struct { + Length int + Md5 string + } + type TransformedObject struct { + Metadata Metadata + } + + transformedObject := TransformedObject{ + Metadata: Metadata{ + Length: len(bodyBytes), + Md5: toMd5(bodyBytes), + }, + } + jsonData, err := json.Marshal(transformedObject) + if err != nil { + return err + } + + // To complete the example, use the AWS SDK to write the response: + // + // import ( + // "github.com/aws/aws-sdk-go-v2/config" + // "github.com/aws/aws-sdk-go-v2/service/s3" + // ) + // + // cfg, err := config.LoadDefaultConfig(context.TODO()) + // if err != nil { + // return err + // } + // svc := s3.NewFromConfig(cfg) + // input := &s3.WriteGetObjectResponseInput{ + // RequestRoute: &event.GetObjectContext.OutputRoute, + // RequestToken: &event.GetObjectContext.OutputToken, + // Body: strings.NewReader(string(jsonData)), + // } + // res, err := svc.WriteGetObjectResponse(ctx, input) + // if err != nil { + // return err + // } + // fmt.Printf("%v", res) + + fmt.Printf("Transformed object metadata: %s\n", jsonData) + return nil + }) +} + +func toMd5(data []byte) string { + hasher := md5.New() + hasher.Write(data) + hash := hasher.Sum(nil) + return hex.EncodeToString(hash) +} diff --git a/events/example_secrets_manager_test.go b/events/example_secrets_manager_test.go new file mode 100644 index 00000000..cb35b971 --- /dev/null +++ b/events/example_secrets_manager_test.go @@ -0,0 +1,31 @@ +package events_test + +import ( + "context" + "fmt" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +// This Lambda function handles a SecretsManager secret rotation event. +// The rotation process has four steps: createSecret, setSecret, testSecret, and finishSecret. +func ExampleSecretsManagerSecretRotationEvent() { + lambda.Start(func(ctx context.Context, event *events.SecretsManagerSecretRotationEvent) error { + fmt.Printf("rotating secret %s with token %s\n", + event.SecretID, event.ClientRequestToken) + + switch event.Step { + case "createSecret": + // create + case "setSecret": + // set + case "finishSecret": + // finish + case "testSecret": + // test + } + + return nil + }) +} diff --git a/events/example_ses_test.go b/events/example_ses_test.go new file mode 100644 index 00000000..a2228a1f --- /dev/null +++ b/events/example_ses_test.go @@ -0,0 +1,20 @@ +package events_test + +import ( + "context" + "fmt" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +func ExampleSimpleEmailEvent() { + lambda.Start(func(ctx context.Context, sesEvent *events.SimpleEmailEvent) error { + for _, record := range sesEvent.Records { + ses := record.SES + fmt.Printf("[%s - %s] Mail = %+v, Receipt = %+v \n", record.EventVersion, record.EventSource, ses.Mail, ses.Receipt) + } + + return nil + }) +} diff --git a/events/example_sqs_test.go b/events/example_sqs_test.go new file mode 100644 index 00000000..26533fe3 --- /dev/null +++ b/events/example_sqs_test.go @@ -0,0 +1,18 @@ +package events_test + +import ( + "context" + "fmt" + + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +func ExampleSQSEvent() { + lambda.Start(func(ctx context.Context, sqsEvent *events.SQSEvent) error { + for _, message := range sqsEvent.Records { + fmt.Printf("The message %s for event source %s = %s \n", message.MessageId, message.EventSource, message.Body) + } + return nil + }) +} diff --git a/lambda/README.md b/lambda/README.md deleted file mode 100644 index dcaca6d1..00000000 --- a/lambda/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview - -[](https://pkg.go.dev/github.com/aws/aws-lambda-go/lambda) diff --git a/lambda/doc.go b/lambda/doc.go new file mode 100644 index 00000000..5008e650 --- /dev/null +++ b/lambda/doc.go @@ -0,0 +1,9 @@ +// Package lambda provides the runtime interface for AWS Lambda functions written in Go. +// +// This package handles communication with the Lambda execution environment, including +// receiving invocation events, managing context, and returning responses. +// +// Use lambda.Start() to register your handler function and begin processing Lambda invocations. +// +// See https://docs.aws.amazon.com/lambda/latest/dg/golang-handler.html +package lambda diff --git a/lambda/entry.go b/lambda/entry.go index da82fab4..6d898f49 100644 --- a/lambda/entry.go +++ b/lambda/entry.go @@ -39,8 +39,11 @@ import ( // Where "TIn" and "TOut" are types compatible with the "encoding/json" standard library. // See https://golang.org/pkg/encoding/json/#Unmarshal for how deserialization behaves // -// "TOut" may also implement the io.Reader interface. -// If "TOut" is both json serializable and implements io.Reader, then the json serialization is used. +// "TOut" may also implement io.Reader to return raw response data (e.g., HTML, XML, binary). +// If the response also implements io.Closer, Close() will be called after sending. +// Errors from Read() (other than io.EOF) are reported as function errors. +// +// Note: If "TOut" is both JSON serializable and implements io.Reader, JSON serialization takes precedence. func Start(handler interface{}) { StartWithOptions(handler) } diff --git a/lambda/example_test.go b/lambda/example_test.go new file mode 100644 index 00000000..10eb8f8c --- /dev/null +++ b/lambda/example_test.go @@ -0,0 +1,102 @@ +package lambda_test + +import ( + "context" + "io" + "log" + "time" + + "github.com/aws/aws-lambda-go/lambda" +) + +func Example() { + lambda.Start(func() (string, error) { + return "Hello λ!", nil + }) +} + +// Handlers can return io.Reader to stream response data. +// This example uses a pipe to send data in chunks with delays. +// +// See https://docs.aws.amazon.com/lambda/latest/dg/configuration-response-streaming.html +func Example_ioReader() { + lambda.Start(func() (io.Reader, error) { + r, w := io.Pipe() + go func() { + defer w.Close() + _, _ = w.Write([]byte("
")) + time.Sleep(100 * time.Millisecond) + _, _ = w.Write([]byte("World!
")) + time.Sleep(100 * time.Millisecond) + _, _ = w.Write([]byte("")) + }() + return r, nil + }) +} + +func ExampleWithContext() { + lambda.StartWithOptions( + func(ctx context.Context) (string, error) { + return ctx.Value("foo").(string), nil + }, + lambda.WithContext(context.WithValue(context.Background(), "foo", "bar")), + ) +} + +func ExampleWithContextValue() { + lambda.StartWithOptions( + func(ctx context.Context) (string, error) { + return ctx.Value("foo").(string), nil + }, + lambda.WithContextValue("foo", "bar"), + ) +} + +func ExampleWithSetEscapeHTML() { + lambda.StartWithOptions( + func() (string, error) { + return "hello!", nil + }, + lambda.WithSetEscapeHTML(true), + ) +} + +func ExampleWithSetIndent() { + lambda.StartWithOptions( + func(event interface{}) (interface{}, error) { + return event, nil + }, + lambda.WithSetIndent(">", " "), + ) +} + +func ExampleWithUseNumber() { + lambda.StartWithOptions( + func(event interface{}) (interface{}, error) { + return event, nil + }, + lambda.WithUseNumber(true), + ) +} + +func ExampleWithDisallowUnknownFields() { + lambda.StartWithOptions( + func(event interface{}) (interface{}, error) { + return event, nil + }, + lambda.WithDisallowUnknownFields(true), + ) +} + +func ExampleWithEnableSIGTERM() { + lambda.StartWithOptions( + func(event interface{}) (interface{}, error) { + return event, nil + }, + lambda.WithEnableSIGTERM(func() { + log.Print("function container shutting down...") + }), + ) +} diff --git a/lambda/handler.go b/lambda/handler.go index 3a644dc2..8df580d4 100644 --- a/lambda/handler.go +++ b/lambda/handler.go @@ -38,15 +38,6 @@ type handlerOptions struct { type Option func(*handlerOptions) // WithContext is a HandlerOption that sets the base context for all invocations of the handler. -// -// Usage: -// -// lambda.StartWithOptions( -// func (ctx context.Context) (string, error) { -// return ctx.Value("foo"), nil -// }, -// lambda.WithContext(context.WithValue(context.Background(), "foo", "bar")) -// ) func WithContext(ctx context.Context) Option { return Option(func(h *handlerOptions) { h.baseContext = ctx @@ -55,15 +46,6 @@ func WithContext(ctx context.Context) Option { // WithContextValue adds a value to the handler context. // If a base context was set using WithContext, that base is used as the parent. -// -// Usage: -// -// lambda.StartWithOptions( -// func (ctx context.Context) (string, error) { -// return ctx.Value("foo"), nil -// }, -// lambda.WithContextValue("foo", "bar") -// ) func WithContextValue(key interface{}, value interface{}) Option { return Option(func(h *handlerOptions) { h.contextValues[key] = value @@ -71,15 +53,6 @@ func WithContextValue(key interface{}, value interface{}) Option { } // WithSetEscapeHTML sets the SetEscapeHTML argument on the underlying json encoder -// -// Usage: -// -// lambda.StartWithOptions( -// func () (string, error) { -// return "hello!>", nil -// }, -// lambda.WithSetEscapeHTML(true), -// ) func WithSetEscapeHTML(escapeHTML bool) Option { return Option(func(h *handlerOptions) { h.jsonResponseEscapeHTML = escapeHTML @@ -87,15 +60,6 @@ func WithSetEscapeHTML(escapeHTML bool) Option { } // WithSetIndent sets the SetIndent argument on the underling json encoder -// -// Usage: -// -// lambda.StartWithOptions( -// func (event any) (any, error) { -// return event, nil -// }, -// lambda.WithSetIndent(">"," "), -// ) func WithSetIndent(prefix, indent string) Option { return Option(func(h *handlerOptions) { h.jsonResponseIndentPrefix = prefix @@ -104,31 +68,13 @@ func WithSetIndent(prefix, indent string) Option { } // WithUseNumber sets the UseNumber option on the underlying json decoder -// -// Usage: -// -// lambda.StartWithOptions( -// func (event any) (any, error) { -// return event, nil -// }, -// lambda.WithUseNumber(true) -// ) func WithUseNumber(useNumber bool) Option { return Option(func(h *handlerOptions) { h.jsonRequestUseNumber = useNumber }) } -// WithUseNumber sets the DisallowUnknownFields option on the underlying json decoder -// -// Usage: -// -// lambda.StartWithOptions( -// func (event any) (any, error) { -// return event, nil -// }, -// lambda.WithDisallowUnknownFields(true) -// ) +// WithDisallowUnknownFields sets the DisallowUnknownFields option on the underlying json decoder func WithDisallowUnknownFields(disallowUnknownFields bool) Option { return Option(func(h *handlerOptions) { h.jsonRequestDisallowUnknownFields = disallowUnknownFields @@ -138,17 +84,6 @@ func WithDisallowUnknownFields(disallowUnknownFields bool) Option { // WithEnableSIGTERM enables SIGTERM behavior within the Lambda platform on container spindown. // SIGKILL will occur ~500ms after SIGTERM. // Optionally, an array of callback functions to run on SIGTERM may be provided. -// -// Usage: -// -// lambda.StartWithOptions( -// func (event any) (any, error) { -// return event, nil -// }, -// lambda.WithEnableSIGTERM(func() { -// log.Print("function container shutting down...") -// }) -// ) func WithEnableSIGTERM(callbacks ...func()) Option { return Option(func(h *handlerOptions) { h.sigtermCallbacks = append(h.sigtermCallbacks, callbacks...) diff --git a/lambdacontext/README.md b/lambdacontext/README.md deleted file mode 100644 index e8c22996..00000000 --- a/lambdacontext/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview - -[](https://pkg.go.dev/github.com/aws/aws-lambda-go/lambdacontext) diff --git a/lambdacontext/context.go b/lambdacontext/context.go index ae11cb47..d75d8282 100644 --- a/lambdacontext/context.go +++ b/lambdacontext/context.go @@ -1,9 +1,12 @@ // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// -// Helpers for accessing context information from an Invoke request. Context information -// is stored in a https://golang.org/pkg/context/#Context. The functions FromContext and NewContext -// are used to retrieving and inserting an instance of LambdaContext. +// Package lambdacontext provides access to Lambda execution context information. +// +// This package allows Lambda functions to access metadata about the current invocation, +// including request ID, function ARN, Cognito identity, and client context. Context +// information is retrieved from the standard Go context.Context using FromContext(). +// +// See https://docs.aws.amazon.com/lambda/latest/dg/golang-context.html package lambdacontext import ( diff --git a/lambdacontext/example_test.go b/lambdacontext/example_test.go new file mode 100644 index 00000000..aa7efd2d --- /dev/null +++ b/lambdacontext/example_test.go @@ -0,0 +1,18 @@ +package lambdacontext_test + +import ( + "context" + "log" + + "github.com/aws/aws-lambda-go/lambda" + "github.com/aws/aws-lambda-go/lambdacontext" +) + +func ExampleFromContext() { + lambda.Start(func(ctx context.Context) (string, error) { + lc, _ := lambdacontext.FromContext(ctx) + log.Printf("Request ID: %s", lc.AwsRequestID) + log.Printf("Function ARN: %s", lc.InvokedFunctionArn) + return "success", nil + }) +} diff --git a/lambdaurl/doc.go b/lambdaurl/doc.go new file mode 100644 index 00000000..f2ef2f00 --- /dev/null +++ b/lambdaurl/doc.go @@ -0,0 +1,7 @@ +// Package lambdaurl serves requests from Lambda Function URLs using http.Handler. +// +// This package allows you to use standard Go http.Handler implementations with Lambda Function URLs, +// making it easy to adapt existing HTTP applications to run on Lambda. +// +// See https://docs.aws.amazon.com/lambda/latest/dg/urls-configuration.html +package lambdaurl