diff --git a/README.md b/README.md index 1a24124ff..ae1797b91 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ serverless install -u https://github.com/serverless/examples/tree/master/folder- | [Aws Golang Auth Examples](https://github.com/serverless/examples/tree/master/aws-golang-auth-examples)
These example shows how to run a Golang lambda with authentication | golang | | [Aws Golang Dynamo Stream To Elasticsearch](https://github.com/serverless/examples/tree/master/aws-golang-dynamo-stream-to-elasticsearch)
This example deploys a DynamoDB Table, an Elasticsearch Node, and a lambda triggered off of a Dynamo Stream which updates an elasticsearch index with the data from the Dynamo Table | golang | | [Aws Golang Http Get Post](https://github.com/serverless/examples/tree/master/aws-golang-http-get-post)
Example on Making Parameterized Get and Post Request with Golang | golang | +| [Aws Golang Rest Api With Dynamodb](https://github.com/serverless/examples/tree/master/aws-golang-rest-api-with-dynamodb)
Serverless CRUD service exposing a REST HTTP interface | golang | | [Aws Golang Simple Http Endpoint](https://github.com/serverless/examples/tree/master/aws-golang-simple-http-endpoint)
Example demonstrates how to setup a simple HTTP GET endpoint with golang | golang | | [Aws Golang Stream Kinesis To Elasticsearch](https://github.com/serverless/examples/tree/master/aws-golang-stream-kinesis-to-elasticsearch)
Pull data from AWS Kinesis streams and forward to elasticsearch | golang | | [Aws Alexa Skill](https://github.com/serverless/examples/tree/master/aws-node-alexa-skill)
This example demonstrates how to use an AWS Lambdas for your custom Alexa skill. | nodeJS | diff --git a/aws-golang-rest-api-with-dynamodb/.gitignore b/aws-golang-rest-api-with-dynamodb/.gitignore new file mode 100644 index 000000000..e6ed61c6f --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/.gitignore @@ -0,0 +1,20 @@ +.serverless +bin +*.pyc +*.pyo + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ diff --git a/aws-golang-rest-api-with-dynamodb/Makefile b/aws-golang-rest-api-with-dynamodb/Makefile new file mode 100644 index 000000000..b0e7a78b6 --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/Makefile @@ -0,0 +1,21 @@ +.PHONY: build clean deploy + +build: + env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/create todos/create.go + env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/delete todos/delete.go + env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/get todos/get.go + env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/list todos/list.go + env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/update todos/update.go + +clean: + rm -rf ./bin ./vendor Gopkg.lock + +deploy: clean build + sls deploy --verbose + +format: + gofmt -w todos/create.go + gofmt -w todos/delete.go + gofmt -w todos/get.go + gofmt -w todos/list.go + gofmt -w todos/update.go diff --git a/aws-golang-rest-api-with-dynamodb/README.md b/aws-golang-rest-api-with-dynamodb/README.md new file mode 100644 index 000000000..88de91291 --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/README.md @@ -0,0 +1,72 @@ + +# aws-golang-rest-api-with-dynamodb + +Build & Deploy +``` +make deploy +``` + +# CRUD Operations + +## Create + +``` +curl --request POST \ + --url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos \ + --header 'Content-Type: application/json' \ + --data '{ + "Title": "Walk the Dog", + "Details": "Complete before 11am" +}' + +curl --request POST \ + --url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos \ + --header 'Content-Type: application/json' \ + --data '{ + "Title": "Mow the Lawn", + "Details": "Remember to buy gas" +}' +``` + +## Read + +``` +curl --request GET \ + --url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos/{id} +``` + +## Update + +``` +curl --request PUT \ + --url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos/0d2263b7-c62d-4df6-8503-bb16ee8dd81 \ + --header 'Content-Type: application/json' \ + --data '{ + "title": "Updated title", + "details": "Updated details" +}' +``` + +## List + +``` +curl --request GET \ + --url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos +``` + + +## Delete + +``` +curl --request DELETE \ + --url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos/0d2263b7-c62d-4df6-8503-bb16ee8dd81 +``` diff --git a/aws-golang-rest-api-with-dynamodb/go.mod b/aws-golang-rest-api-with-dynamodb/go.mod new file mode 100644 index 000000000..8f38365ba --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/go.mod @@ -0,0 +1,9 @@ +module github.com/serverless/examples/aws-golang-rest-api-with-dynamodb + +go 1.15 + +require ( + github.com/aws/aws-lambda-go v1.22.0 + github.com/aws/aws-sdk-go v1.37.1 // indirect + github.com/google/uuid v1.2.0 // indirect +) diff --git a/aws-golang-rest-api-with-dynamodb/go.sum b/aws-golang-rest-api-with-dynamodb/go.sum new file mode 100644 index 000000000..f4e0f8a8d --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/go.sum @@ -0,0 +1,36 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/aws/aws-lambda-go v1.22.0 h1:X7BKqIdfoJcbsEIi+Lrt5YjX1HnZexIbNWOQgkYKgfE= +github.com/aws/aws-lambda-go v1.22.0/go.mod h1:jJmlefzPfGnckuHdXX7/80O3BvUUi12XOkbv4w9SGLU= +github.com/aws/aws-sdk-go v1.37.1 h1:BTHmuN+gzhxkvU9sac2tZvaY0gV9ihbHw+KxZOecYvY= +github.com/aws/aws-sdk-go v1.37.1/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/aws-golang-rest-api-with-dynamodb/package.json b/aws-golang-rest-api-with-dynamodb/package.json new file mode 100644 index 000000000..aab92227d --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/package.json @@ -0,0 +1,7 @@ +{ + "name": "aws-golang-rest-api-with-dynamodb", + "version": "1.0.0", + "description": "Serverless CRUD service exposing a REST HTTP interface", + "author": "", + "license": "MIT" + } diff --git a/aws-golang-rest-api-with-dynamodb/serverless.yml b/aws-golang-rest-api-with-dynamodb/serverless.yml new file mode 100644 index 000000000..6749c1964 --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/serverless.yml @@ -0,0 +1,95 @@ +app: aws-golang-rest-api-with-dynamodb +service: aws-golang-rest-api-with-dynamodb + +frameworkVersion: ">=1.1.0 <=2.1.1" + +provider: + name: aws + runtime: go1.x + environment: + DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage} + iamRoleStatements: + - Effect: Allow + Action: + - dynamodb:Query + - dynamodb:Scan + - dynamodb:GetItem + - dynamodb:PutItem + - dynamodb:UpdateItem + - dynamodb:DeleteItem + Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}" + +functions: + create: + handler: bin/create + package: + include: + - ./bin/create + events: + - http: + path: todos + method: post + cors: true + + list: + handler: bin/list + package: + include: + - ./bin/list + events: + - http: + path: todos + method: get + cors: true + + get: + handler: bin/get + package: + include: + - ./bin/get + events: + - http: + path: todos/{id} + method: get + cors: true + + update: + handler: bin/update + package: + include: + - ./bin/update + events: + - http: + path: todos/{id} + method: put + cors: true + + delete: + handler: bin/delete + package: + include: + - ./bin/deleteBin + events: + - http: + path: todos/{id} + method: delete + cors: true + +resources: + Resources: + TodosDynamoDbTable: + Type: 'AWS::DynamoDB::Table' + DeletionPolicy: Retain + Properties: + AttributeDefinitions: + - + AttributeName: id + AttributeType: S + KeySchema: + - + AttributeName: id + KeyType: HASH + ProvisionedThroughput: + ReadCapacityUnits: 1 + WriteCapacityUnits: 1 + TableName: ${self:provider.environment.DYNAMODB_TABLE} diff --git a/aws-golang-rest-api-with-dynamodb/todos/create.go b/aws-golang-rest-api-with-dynamodb/todos/create.go new file mode 100644 index 000000000..60eb4339a --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/todos/create.go @@ -0,0 +1,90 @@ +package main + +import ( + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" + "github.com/google/uuid" + + "encoding/json" + "fmt" + "os" +) + +type Item struct { + Id string `json:"id,omitempty"` + Title string `json:"title"` + Details string `json:"details"` +} + +func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { + + // Creating session for client + sess := session.Must(session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + })) + + // Create DynamoDB client + svc := dynamodb.New(sess) + + // New uuid for item id + itemUuid := uuid.New().String() + + fmt.Println("Generated new item uuid:", itemUuid) + + // Unmarshal to Item to access object properties + itemString := request.Body + itemStruct := Item{} + json.Unmarshal([]byte(itemString), &itemStruct) + + if itemStruct.Title == "" { + return events.APIGatewayProxyResponse{StatusCode: 400}, nil + } + + // Create new item of type item + item := Item{ + Id: itemUuid, + Title: itemStruct.Title, + Details: itemStruct.Details, + } + + // Marshal to dynamobb item + av, err := dynamodbattribute.MarshalMap(item) + if err != nil { + fmt.Println("Error marshalling item: ", err.Error()) + return events.APIGatewayProxyResponse{StatusCode: 500}, nil + } + + tableName := os.Getenv("DYNAMODB_TABLE") + + // Build put item input + fmt.Println("Putting item: %v", av) + input := &dynamodb.PutItemInput{ + Item: av, + TableName: aws.String(tableName), + } + + // PutItem request + _, err = svc.PutItem(input) + + // Checking for errors, return error + if err != nil { + fmt.Println("Got error calling PutItem: ", err.Error()) + return events.APIGatewayProxyResponse{StatusCode: 500}, nil + } + + // Marshal item to return + itemMarshalled, err := json.Marshal(item) + + fmt.Println("Returning item: ", string(itemMarshalled)) + + //Returning response with AWS Lambda Proxy Response + return events.APIGatewayProxyResponse{Body: string(itemMarshalled), StatusCode: 200}, nil +} + +func main() { + lambda.Start(Handler) +} diff --git a/aws-golang-rest-api-with-dynamodb/todos/delete.go b/aws-golang-rest-api-with-dynamodb/todos/delete.go new file mode 100644 index 000000000..e67e6663f --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/todos/delete.go @@ -0,0 +1,55 @@ +package main + +import ( + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/dynamodb" + + "fmt" + "os" +) + +type Item struct { + Id string `json:"id,omitempty"` + Title string `json:"title"` + Details string `json:"details"` +} + +func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { + + // Creating session for client + sess := session.Must(session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + })) + + // Create DynamoDB client + svc := dynamodb.New(sess) + + pathParamId := request.PathParameters["id"] + + input := &dynamodb.DeleteItemInput{ + Key: map[string]*dynamodb.AttributeValue{ + "id": { + S: aws.String(pathParamId), + }, + }, + TableName: aws.String(os.Getenv("DYNAMODB_TABLE")), + } + + // DeleteItem request + _, err := svc.DeleteItem(input) + + // Checking for errors, return error + if err != nil { + fmt.Println("Got error calling DeleteItem: ", err.Error()) + return events.APIGatewayProxyResponse{StatusCode: 500}, nil + } + + return events.APIGatewayProxyResponse{StatusCode: 204}, nil +} + +func main() { + lambda.Start(Handler) +} diff --git a/aws-golang-rest-api-with-dynamodb/todos/get.go b/aws-golang-rest-api-with-dynamodb/todos/get.go new file mode 100644 index 000000000..8d9f66bbd --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/todos/get.go @@ -0,0 +1,79 @@ +package main + +import ( + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" + + "encoding/json" + "fmt" + "os" +) + +type Item struct { + Id string `json:"id,omitempty"` + Title string `json:"title"` + Details string `json:"details"` +} + +func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { + + // Creating session for client + sess := session.Must(session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + })) + + // Create DynamoDB client + svc := dynamodb.New(sess) + + // Getting id from path parameters + pathParamId := request.PathParameters["id"] + + fmt.Println("Derived pathParamId from path params: ", pathParamId) + + // GetItem request + result, err := svc.GetItem(&dynamodb.GetItemInput{ + TableName: aws.String(os.Getenv("DYNAMODB_TABLE")), + Key: map[string]*dynamodb.AttributeValue{ + "id": { + S: aws.String(pathParamId), + }, + }, + }) + + // Checking for errors, return error + if err != nil { + fmt.Println(err.Error()) + return events.APIGatewayProxyResponse{StatusCode: 500}, nil + } + + // Checking type + if len(result.Item) == 0 { + return events.APIGatewayProxyResponse{StatusCode: 404}, nil + } + + // Created item of type Item + item := Item{} + + // result is of type *dynamodb.GetItemOutput + // result.Item is of type map[string]*dynamodb.AttributeValue + // UnmarshallMap result.item into item + err = dynamodbattribute.UnmarshalMap(result.Item, &item) + + if err != nil { + panic(fmt.Sprintf("Failed to UnmarshalMap result.Item: ", err)) + } + + // Marshal to type []uint8 + marshalledItem, err := json.Marshal(item) + + // Return marshalled item + return events.APIGatewayProxyResponse{Body: string(marshalledItem), StatusCode: 200}, nil +} + +func main() { + lambda.Start(Handler) +} diff --git a/aws-golang-rest-api-with-dynamodb/todos/list.go b/aws-golang-rest-api-with-dynamodb/todos/list.go new file mode 100644 index 000000000..a3d41a885 --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/todos/list.go @@ -0,0 +1,77 @@ +package main + +import ( + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" + + "encoding/json" + "fmt" + "os" +) + +type Item struct { + Id string `json:"id,omitempty"` + Title string `json:"title"` + Details string `json:"details"` +} + +func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { + + // Creating session for client + sess := session.Must(session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + })) + + // Create DynamoDB client + svc := dynamodb.New(sess) + + // Build the query input parameters + params := &dynamodb.ScanInput{ + TableName: aws.String(os.Getenv("DYNAMODB_TABLE")), + } + + // Scan table + result, err := svc.Scan(params) + + // Checking for errors, return error + if err != nil { + fmt.Println("Query API call failed: ", err.Error()) + return events.APIGatewayProxyResponse{StatusCode: 500}, nil + } + + var itemArray []Item + + for _, i := range result.Items { + item := Item{} + + // result is of type *dynamodb.GetItemOutput + // result.Item is of type map[string]*dynamodb.AttributeValue + // UnmarshallMap result.item to item + err = dynamodbattribute.UnmarshalMap(i, &item) + + if err != nil { + fmt.Println("Got error unmarshalling: ", err.Error()) + return events.APIGatewayProxyResponse{StatusCode: 500}, nil + } + + itemArray = append(itemArray, item) + } + + fmt.Println("itemArray: ", itemArray) + + itemArrayString, err := json.Marshal(itemArray) + if err != nil { + fmt.Println("Got error marshalling result: ", err.Error()) + return events.APIGatewayProxyResponse{StatusCode: 500}, nil + } + + return events.APIGatewayProxyResponse{Body: string(itemArrayString), StatusCode: 200}, nil +} + +func main() { + lambda.Start(Handler) +} diff --git a/aws-golang-rest-api-with-dynamodb/todos/update.go b/aws-golang-rest-api-with-dynamodb/todos/update.go new file mode 100644 index 000000000..7029aa37e --- /dev/null +++ b/aws-golang-rest-api-with-dynamodb/todos/update.go @@ -0,0 +1,79 @@ +package main + +import ( + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/dynamodb" + + "encoding/json" + "fmt" + "os" +) + +type Item struct { + Id string `json:"id,omitempty"` + Title string `json:"title"` + Details string `json:"details"` +} + +func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { + + // Creating session for client + sess := session.Must(session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + })) + + // Create DynamoDB client + svc := dynamodb.New(sess) + + pathParamId := request.PathParameters["id"] + + itemString := request.Body + itemStruct := Item{} + json.Unmarshal([]byte(itemString), &itemStruct) + + info := Item{ + Title: itemStruct.Title, + Details: itemStruct.Details, + } + + fmt.Println("Updating title to: ", info.Title) + fmt.Println("Updating details to: ", info.Details) + + // Prepare input for Update Item + input := &dynamodb.UpdateItemInput{ + ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{ + ":t": { + S: aws.String(info.Title), + }, + ":d": { + S: aws.String(info.Details), + }, + }, + TableName: aws.String(os.Getenv("DYNAMODB_TABLE")), + Key: map[string]*dynamodb.AttributeValue{ + "id": { + S: aws.String(pathParamId), + }, + }, + ReturnValues: aws.String("UPDATED_NEW"), + UpdateExpression: aws.String("set title = :t, details = :d"), + } + + // UpdateItem request + _, err := svc.UpdateItem(input) + + // Checking for errors, return error + if err != nil { + fmt.Println(err.Error()) + return events.APIGatewayProxyResponse{StatusCode: 500}, nil + } + + return events.APIGatewayProxyResponse{StatusCode: 204}, nil +} + +func main() { + lambda.Start(Handler) +}