28/12/2021 - AWS, DOCKER, GO
Uygulamanızda tek bir AWS Lambda işlevinin kullanılması basittir ancak birden çok işlevin kullanılması biraz karmaşık olabilir. Bu örnekte, isteğin hangi işleyiciye aktarılması gerektiğini bulmak için bir strateji benimseyeceğiz. Burada ana işleyici gerçek isteği inceler. Ardından event
anahtarındaki değeri kontrol eder ve body
anahtarındaki kodlanmış değeri ilgili işleve iletir.
package main
import (
"github.com/aws/aws-lambda-go/lambda"
"github.com/you/user"
)
func main() {
lambda.Start(user.User{}.Handle)
}
package user
import (
"context"
"encoding/json"
"fmt"
"github.com/aws/aws-lambda-go/lambdacontext"
)
type HandleRequest struct {
Event string `json:"event"`
Body json.RawMessage `json:"body"`
}
type HandleResponse struct {
OK bool `json:"ok"`
ReqID string `json:"req_id"`
}
type User struct {
// Some dependencies
}
func (u User) Handle(ctx context.Context, req HandleRequest) (interface{}, error) {
var reqID string
if lc, ok := lambdacontext.FromContext(ctx); ok {
reqID = lc.AwsRequestID
}
select {
case <-ctx.Done():
return HandleResponse{OK: false, ReqID: reqID}, fmt.Errorf("request timeout: %w", ctx.Err())
default:
}
switch req.Event {
case "create":
var dest CreateRequest
if err := json.Unmarshal(req.Body, &dest); err != nil {
return nil, err
}
return u.Create(ctx, reqID, dest)
case "delete":
var dest DeleteRequest
if err := json.Unmarshal(req.Body, &dest); err != nil {
return nil, err
}
return u.Delete(ctx, reqID, dest)
}
return HandleResponse{OK: false, ReqID: reqID}, fmt.Errorf("%s is an unknown event", req.Event)
}
package user
import (
"context"
"fmt"
"time"
)
type CreateRequest struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
type CreateResponse struct {
OK bool `json:"ok"`
ID int64 `json:"id"`
ReqID string `json:"req_id"`
}
func (u User) Create(_ context.Context, reqID string, req CreateRequest) (CreateResponse, error) {
if req.FirstName == "" {
return CreateResponse{OK: false, ID: 0, ReqID: reqID}, fmt.Errorf("the first_name is missing")
}
if req.LastName == "" {
return CreateResponse{OK: false, ID: 0, ReqID: reqID}, fmt.Errorf("the last_name is missing")
}
return CreateResponse{OK: true, ID: time.Now().UnixNano(), ReqID: reqID}, nil
}
package user
import (
"context"
"fmt"
)
type DeleteRequest struct {
ID string `json:"id"`
}
type DeleteResponse struct {
OK bool `json:"ok"`
ReqID string `json:"req_id"`
}
func (u User) Delete(_ context.Context, reqID string, req DeleteRequest) (DeleteResponse, error) {
if req.ID == "" {
return DeleteResponse{OK: false, ReqID: reqID}, fmt.Errorf("the id key is missing")
}
return DeleteResponse{OK: true, ReqID: reqID}, nil
}
// Setup
$ GOOS=linux CGO_ENABLED=0 go build -ldflags "-s -w" -o app main.go
$ zip app.zip app
$ aws --profile localstack --endpoint-url http://localhost:4566 lambda create-function --function-name user-create --handler app --zip-file fileb://app.zip --runtime go1.x --role some-role --description "Creates a new user"
// Create
$ aws --profile localstack --endpoint-url http://localhost:4566 lambda invoke --function-name user-create --cli-binary-format raw-in-base64-out --payload '{"event":"create","body":{"first_name":"fn","last_name":"ln"}}' create.json
// create.json: {"id":1640808733146866600,"ok":true,"req_id":"c39c8a10-1c19-11e1-6810-d0f60acc866a"}
// Delete
$ aws --profile localstack --endpoint-url http://localhost:4566 lambda invoke --function-name user-create --cli-binary-format raw-in-base64-out --payload '{"event":"delete","body":{"id":"idx"}}' delete.json
// delete.json: {"ok":true,"req_id":"54790f38-268b-1a30-9406-6cbfe0fb2db0"}