To create a GO app the see Chapter Simple programm.
Let`s look at the source in /lambda-go/simple-lambda
package main
import (
"fmt"
"context"
"github.com/aws/aws-lambda-go/lambda"
)
type MyEvent struct {
Name string `json:"name"`
}
func HandleRequest(ctx context.Context, name MyEvent) (string, error) {
return fmt.Sprintf("Hiho %s!", name.Name ), nil
}
func main() {
lambda.Start(HandleRequest)
}
1 package main
2
3 import (
4 "fmt"
5 "context"
6 "github.com/aws/aws-lambda-go/lambda"
7 )
8
9 type MyEvent struct {
10 Name string `json:"name"`
11 }
12
13 func HandleRequest(ctx context.Context, name MyEvent) (string, error) {
14 return fmt.Sprintf("Hiho %s!", name.Name ), nil
15 }
16
17 func main() {
18 lambda.Start(HandleRequest)
19 }
In line 18 the main function calls the lambda handler. This function is imported in line 6 from “github.com/aws/aws-lambda-go/lambda”.
This handler, here in line 13 is then called with a context and a JSON event.
The input for HandleRequest is a context, from which we can get the lambdacontext. The context stores things like the FunctionName, the AwsRequestID and other things.
The input, which is the payload of the invocation has to be defined in a struct, here MyEvent in line 9.
If you invoke Lambda with an AWS event, all the events are defined in AWS Event definitions.
Working with own events, you define the struct.
So with:
9 type MyEvent struct {
10 Name string `json:"name"`
11 }
the input event could be:
{
"name": "megaproaktiv"
}
Build
env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./dist/main main.go
This takes 0,4 seconds on my computer the output:
time env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./dist/main main.go
env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./dist/main main.go 0,26s user 0,30s system 136% cpu 0,409 total
change file execution permission
chmod +x ./dist/main
package the file in a zip
Lambda upload only accept zipped files, so zip it:
cd ./dist && zip main.zip main && cd ..
Output:
updating: main (deflated 60%)
Part | meaning |
---|---|
env GOOS=linux | build for linux operation system |
GOARCH=amd64 | build for intel/amd. You need this e.g. if you are working with an M1 mac, which is arm based |
go build | build call |
-ldflags="-s -w" | See go help build , omit the symbol table, debug information to get a smaller binary |
-o ./dist/main | ouput in directory “dist” (short for distribution), file main |
main.go | the go file to build |
You may need to compile packages with CGO_ENABLED=0 set on Linux.
With go you can build the binary for different operations systems (os). Without any GOOS/GOARCH GO will take the current os and architecture, so that the app runs on your machine.
With AWS Lambda, the GOOS is always linux. The GOARCH can be amd64 for intel or arm for Gravition.
We deploy the code directly from the AWS CLI with:
Deploy with AWS CLI
aws lambda update-function-code --function-name gosimple --zip-file fileb://./dist/main.zip
The name gosimple has to be exactly the name you set on the creation of the lambda function.
Output:
{
"FunctionName": "gosimple",
"FunctionArn": "arn:aws:lambda:eu-central-1:555544443333:function:gosimple",
"Runtime": "go1.x",
"Role": "arn:aws:iam::555544443333:role/service-role/gosimple-role-ivx29crw",
"Handler": "hello",
"CodeSize": 2380085,
"Description": "",
"Timeout": 15,
"MemorySize": 512,
"LastModified": "2021-10-31T13:56:03.295+0000",
"CodeSha256": "JnDGwqj9oKxrb0mwrtLBdi6PaPVkimpMHff0Yb0bPX8=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "898b0cc5-0ade-43f0-a798-0187d74dea91",
"State": "Active",
"LastUpdateStatus": "Successful",
"PackageType": "Zip",
"Architectures": [
"x86_64"
]
}
The direct deployment has limits on the file size. Deploy from S3 or with Container images for larger files. See AWS Lambda limits for size limits.
In the source code, there is a json file in testdata/event.json
.
We give the AWS CLI Lambda invoke call the payload event.json as input parameter. Because we use the fileb:
function, it does not have to be base64 encoded.
So this call invokes the lambda from the AWS CLI:
aws lambda invoke --function-name gosimple --payload fileb://testdata/event.json testdata/lambda.out
You get the output from the AWS Lambda invoke call as on output:
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
This is not the answer from the Lambda function, but the answer from the Lambda services, which tells you, that the invocation succeeded.
The output from the Lambda function is in `testdata/lambda.out``
cat testdata/lambda.out
"Hiho megaproaktiv!"%
In the source dir there ist the Taskfile.yml
.
The calls are included there, so you can:
Deploy
task deploy
For deploy i define a variable NAME, because the function name is often used in the task file. And you can also get this name from AWS Systems Manager Parameter Store or CloudFormation output.
vars:
NAME: gosimple
deploy:
desc: Deploy only Lambda function
deps: [build]
cmds:
- aws lambda update-function-code --function-name {{.NAME}} --zip-file fileb://./dist/main.zip
This depends on the build task:
build:
desc: build go
cmds:
- env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./dist/main main.go
- chmod +x ./dist/main
- cd ./dist && zip main.zip main
Invoke
task invoke
The creation and deployment with the CDK, see the Chapter Lambda with CDK overview is much better suited for complex deployments. But as you have seen here, the setup for single functions is faster.
To create a go app: Chapter Simple programm
See the full source on github.