Create a Lambda function that receives a request from API Gateway and puts an item into DynamoDB.
package main
import (
"github.com/aws/aws-cdk-go/awscdk/v2"
"github.com/aws/aws-cdk-go/awscdk/v2/awsapigateway"
"github.com/aws/aws-cdk-go/awscdk/v2/awsdynamodb"
"github.com/aws/aws-cdk-go/awscdk/v2/awsiam"
"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
"github.com/aws/constructs-go/constructs/v10"
"github.com/aws/jsii-runtime-go"
)
type ApigwLambdaDynamodbCdkGolangStackProps struct {
awscdk.StackProps
}
// DynamoDB related constants
const (
tableName = "users-table"
partitionKeyName = "email"
dynamoDBTableNameEnvVar = "DYNAMODB_TABLE_NAME"
)
// Lambda function related constants
const (
lambdaHandlerName = "my-func" //same as Go binary name
functionZipFilePath = "../function/function.zip"
)
// API Gateway related constants
const (
apigwResourceName = "users"
httpMethod = "POST"
)
func NewApigwLambdaDynamodbCdkGolangStack(scope constructs.Construct, id string, props *ApigwLambdaDynamodbCdkGolangStackProps) awscdk.Stack {
var sprops awscdk.StackProps
if props != nil {
sprops = props.StackProps
}
stack := awscdk.NewStack(scope, &id, &sprops)
// DynamoDB partition key
partitionKey := &awsdynamodb.Attribute{Name: jsii.String(partitionKeyName), Type: awsdynamodb.AttributeType_STRING}
// DynamoDB table
dynamoDBTable := awsdynamodb.NewTable(stack, jsii.String("dynamodb-table"), &awsdynamodb.TableProps{TableName: jsii.String(tableName), BillingMode: awsdynamodb.BillingMode_PAY_PER_REQUEST, PartitionKey: partitionKey, RemovalPolicy: awscdk.RemovalPolicy_DESTROY})
// environment variable for Lambda function
lambdaEnvVar := &map[string]*string{dynamoDBTableNameEnvVar: dynamoDBTable.TableName()}
// lambda function packaged as zip file
function := awslambda.NewFunction(stack, jsii.String("lambda-function"), &awslambda.FunctionProps{Runtime: awslambda.Runtime_GO_1_X(), Handler: jsii.String(lambdaHandlerName), Code: awslambda.AssetCode_FromAsset(jsii.String(functionZipFilePath), nil), Environment: lambdaEnvVar})
// policy to allow DynamoDB PutItem calls
dynamoDBPutItemPolicy := awsiam.NewPolicy(stack, jsii.String("policy"), &awsiam.PolicyProps{PolicyName: jsii.String("LambdaDynamoDBPutItemPolicy"), Statements: &[]awsiam.PolicyStatement{awsiam.NewPolicyStatement(&awsiam.PolicyStatementProps{Effect: awsiam.Effect_ALLOW, Actions: jsii.Strings("dynamodb:PutItem"), Resources: jsii.Strings(*dynamoDBTable.TableArn())})}})
// attach the policy to an IAM role which is created during Lambda creation
function.Role().AttachInlinePolicy(dynamoDBPutItemPolicy)
// API Gateway REST API
restapi := awsapigateway.NewRestApi(stack, jsii.String("rest-apigw"), &awsapigateway.RestApiProps{EndpointTypes: &[]awsapigateway.EndpointType{awsapigateway.EndpointType_REGIONAL}, RestApiName: jsii.String("apigw-users")})
// explict method definition (instead of proxy)
restapi.Root().AddMethod(jsii.String(httpMethod), awsapigateway.NewLambdaIntegration(function, &awsapigateway.LambdaIntegrationOptions{AllowTestInvoke: jsii.Bool(false)}), restapi.Root().DefaultMethodOptions())
return stack
}
func main() {
app := awscdk.NewApp(nil)
NewApigwLambdaDynamodbCdkGolangStack(app, "ServerlessCDKGoStack", &ApigwLambdaDynamodbCdkGolangStackProps{
awscdk.StackProps{
Env: env(),
},
})
app.Synth(nil)
}
// env determines the AWS environment (account+region) in which our stack is to
// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html
func env() *awscdk.Environment {
return nil
}
git clone https://github.com/aws-samples/serverless-patterns
cd serverless-patterns/apigw-lambda-dynamodb-cdk-go