Skip to content

Commit 83f7c36

Browse files
committed
aws-golang-rest-api-with-dynamodb
1 parent 85e2b06 commit 83f7c36

File tree

13 files changed

+628
-0
lines changed

13 files changed

+628
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ serverless install -u https://github.com/serverless/examples/tree/master/folder-
4747
| [Aws Golang Auth Examples](https://github.com/serverless/examples/tree/master/aws-golang-auth-examples) <br/> These example shows how to run a Golang lambda with authentication | golang |
4848
| [Aws Golang Dynamo Stream To Elasticsearch](https://github.com/serverless/examples/tree/master/aws-golang-dynamo-stream-to-elasticsearch) <br/> 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 |
4949
| [Aws Golang Http Get Post](https://github.com/serverless/examples/tree/master/aws-golang-http-get-post) <br/> Example on Making Parameterized Get and Post Request with Golang | golang |
50+
| [Aws Golang Rest Api With Dynamodb](https://github.com/serverless/examples/tree/master/aws-golang-rest-api-with-dynamodb) <br/> Serverless CRUD service exposing a REST HTTP interface | golang |
5051
| [Aws Golang Simple Http Endpoint](https://github.com/serverless/examples/tree/master/aws-golang-simple-http-endpoint) <br/> Example demonstrates how to setup a simple HTTP GET endpoint with golang | golang |
5152
| [Aws Golang Stream Kinesis To Elasticsearch](https://github.com/serverless/examples/tree/master/aws-golang-stream-kinesis-to-elasticsearch) <br/> Pull data from AWS Kinesis streams and forward to elasticsearch | golang |
5253
| [Aws Alexa Skill](https://github.com/serverless/examples/tree/master/aws-node-alexa-skill) <br/> This example demonstrates how to use an AWS Lambdas for your custom Alexa skill. | nodeJS |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.serverless
2+
bin
3+
*.pyc
4+
*.pyo
5+
6+
# Binaries for programs and plugins
7+
*.exe
8+
*.exe~
9+
*.dll
10+
*.so
11+
*.dylib
12+
13+
# Test binary, built with `go test -c`
14+
*.test
15+
16+
# Output of the go coverage tool, specifically when used with LiteIDE
17+
*.out
18+
19+
# Dependency directories (remove the comment below to include it)
20+
# vendor/
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.PHONY: build clean deploy
2+
3+
build:
4+
env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/create todos/create.go
5+
env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/delete todos/delete.go
6+
env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/get todos/get.go
7+
env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/list todos/list.go
8+
env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/update todos/update.go
9+
10+
clean:
11+
rm -rf ./bin ./vendor Gopkg.lock
12+
13+
deploy: clean build
14+
sls deploy --verbose
15+
16+
format:
17+
gofmt -w todos/create.go
18+
gofmt -w todos/delete.go
19+
gofmt -w todos/get.go
20+
gofmt -w todos/list.go
21+
gofmt -w todos/update.go
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<!--
2+
title: 'aws-golang-rest-api-with-dynamodb'
3+
description: 'Boilerplate code for Golang CRUD Operations'
4+
framework: v1
5+
platform: AWS
6+
language: Go
7+
authorLink: 'https://github.com/gsweene2'
8+
authorName: 'Garrett Sweeney'
9+
authorAvatar: 'https://avatars.githubusercontent.com/u/14845943?s=400&u=6d79e8f042cd3d30643ba4598515cae24be69ec3&v=4'
10+
-->
11+
# aws-golang-rest-api-with-dynamodb
12+
13+
Build & Deploy
14+
```
15+
make deploy
16+
```
17+
18+
# CRUD Operations
19+
20+
## Create
21+
22+
```
23+
curl --request POST \
24+
--url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos \
25+
--header 'Content-Type: application/json' \
26+
--data '{
27+
"Title": "Walk the Dog",
28+
"Details": "Complete before 11am"
29+
}'
30+
31+
curl --request POST \
32+
--url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos \
33+
--header 'Content-Type: application/json' \
34+
--data '{
35+
"Title": "Mow the Lawn",
36+
"Details": "Remember to buy gas"
37+
}'
38+
```
39+
40+
## Read
41+
42+
```
43+
curl --request GET \
44+
--url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos/{id}
45+
```
46+
47+
## Update
48+
49+
```
50+
curl --request PUT \
51+
--url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos/0d2263b7-c62d-4df6-8503-bb16ee8dd81 \
52+
--header 'Content-Type: application/json' \
53+
--data '{
54+
"title": "Updated title",
55+
"details": "Updated details"
56+
}'
57+
```
58+
59+
## List
60+
61+
```
62+
curl --request GET \
63+
--url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos
64+
```
65+
66+
67+
## Delete
68+
69+
```
70+
curl --request DELETE \
71+
--url https://fz3n8nstdf.execute-api.us-east-1.amazonaws.com/dev/todos/0d2263b7-c62d-4df6-8503-bb16ee8dd81
72+
```
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module github.com/serverless/examples/aws-golang-rest-api-with-dynamodb
2+
3+
go 1.15
4+
5+
require (
6+
github.com/aws/aws-lambda-go v1.22.0
7+
github.com/aws/aws-sdk-go v1.37.1 // indirect
8+
github.com/google/uuid v1.2.0 // indirect
9+
)
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2+
github.com/aws/aws-lambda-go v1.22.0 h1:X7BKqIdfoJcbsEIi+Lrt5YjX1HnZexIbNWOQgkYKgfE=
3+
github.com/aws/aws-lambda-go v1.22.0/go.mod h1:jJmlefzPfGnckuHdXX7/80O3BvUUi12XOkbv4w9SGLU=
4+
github.com/aws/aws-sdk-go v1.37.1 h1:BTHmuN+gzhxkvU9sac2tZvaY0gV9ihbHw+KxZOecYvY=
5+
github.com/aws/aws-sdk-go v1.37.1/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
6+
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
7+
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
8+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10+
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
11+
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
12+
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
13+
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
14+
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
15+
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
16+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
17+
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
18+
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
19+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
20+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
21+
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
22+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
23+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
24+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
25+
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
26+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
27+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
28+
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
29+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
30+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
31+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
32+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
33+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
34+
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
35+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
36+
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "aws-golang-rest-api-with-dynamodb",
3+
"version": "1.0.0",
4+
"description": "Serverless CRUD service exposing a REST HTTP interface",
5+
"author": "",
6+
"license": "MIT"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
org: garrettdsweeney
2+
app: aws-golang-rest-api-with-dynamodb
3+
service: aws-golang-rest-api-with-dynamodb
4+
5+
frameworkVersion: ">=1.1.0 <=2.1.1"
6+
7+
provider:
8+
name: aws
9+
runtime: go1.x
10+
environment:
11+
DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
12+
iamRoleStatements:
13+
- Effect: Allow
14+
Action:
15+
- dynamodb:Query
16+
- dynamodb:Scan
17+
- dynamodb:GetItem
18+
- dynamodb:PutItem
19+
- dynamodb:UpdateItem
20+
- dynamodb:DeleteItem
21+
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
22+
23+
functions:
24+
create:
25+
handler: bin/create
26+
package:
27+
include:
28+
- ./bin/create
29+
events:
30+
- http:
31+
path: todos
32+
method: post
33+
cors: true
34+
35+
list:
36+
handler: bin/list
37+
package:
38+
include:
39+
- ./bin/list
40+
events:
41+
- http:
42+
path: todos
43+
method: get
44+
cors: true
45+
46+
get:
47+
handler: bin/get
48+
package:
49+
include:
50+
- ./bin/get
51+
events:
52+
- http:
53+
path: todos/{id}
54+
method: get
55+
cors: true
56+
57+
update:
58+
handler: bin/update
59+
package:
60+
include:
61+
- ./bin/update
62+
events:
63+
- http:
64+
path: todos/{id}
65+
method: put
66+
cors: true
67+
68+
delete:
69+
handler: bin/delete
70+
package:
71+
include:
72+
- ./bin/deleteBin
73+
events:
74+
- http:
75+
path: todos/{id}
76+
method: delete
77+
cors: true
78+
79+
resources:
80+
Resources:
81+
TodosDynamoDbTable:
82+
Type: 'AWS::DynamoDB::Table'
83+
DeletionPolicy: Retain
84+
Properties:
85+
AttributeDefinitions:
86+
-
87+
AttributeName: id
88+
AttributeType: S
89+
KeySchema:
90+
-
91+
AttributeName: id
92+
KeyType: HASH
93+
ProvisionedThroughput:
94+
ReadCapacityUnits: 1
95+
WriteCapacityUnits: 1
96+
TableName: ${self:provider.environment.DYNAMODB_TABLE}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package main
2+
3+
import (
4+
"github.com/aws/aws-lambda-go/events"
5+
"github.com/aws/aws-lambda-go/lambda"
6+
"github.com/aws/aws-sdk-go/aws"
7+
"github.com/aws/aws-sdk-go/aws/session"
8+
"github.com/aws/aws-sdk-go/service/dynamodb"
9+
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
10+
"github.com/google/uuid"
11+
12+
"encoding/json"
13+
"fmt"
14+
"os"
15+
)
16+
17+
type Item struct {
18+
Id string `json:"id,omitempty"`
19+
Title string `json:"title"`
20+
Details string `json:"details"`
21+
}
22+
23+
func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
24+
25+
// Creating session for client
26+
sess := session.Must(session.NewSessionWithOptions(session.Options{
27+
SharedConfigState: session.SharedConfigEnable,
28+
}))
29+
30+
// Create DynamoDB client
31+
svc := dynamodb.New(sess)
32+
33+
itemUuid := uuid.New().String()
34+
35+
fmt.Println("Generated new item uuid:", itemUuid)
36+
37+
itemString := request.Body
38+
itemStruct := Item{}
39+
json.Unmarshal([]byte(itemString), &itemStruct)
40+
41+
item := Item{
42+
Id: itemUuid,
43+
Title: itemStruct.Title,
44+
Details: itemStruct.Details,
45+
}
46+
47+
av, err := dynamodbattribute.MarshalMap(item)
48+
if err != nil {
49+
fmt.Println("Error marshalling item: ", err.Error())
50+
return events.APIGatewayProxyResponse{Body: "Yikes", StatusCode: 500}, nil
51+
}
52+
53+
tableName := os.Getenv("DYNAMODB_TABLE")
54+
55+
fmt.Println("Putting item: %v", av)
56+
57+
input := &dynamodb.PutItemInput{
58+
Item: av,
59+
TableName: aws.String(tableName),
60+
}
61+
62+
// PutItem request
63+
_, err = svc.PutItem(input)
64+
65+
// Checking for errors, return error
66+
if err != nil {
67+
fmt.Println("Got error calling PutItem: ", err.Error())
68+
return events.APIGatewayProxyResponse{Body: "Yikes", StatusCode: 500}, nil
69+
}
70+
71+
item_marshalled, err := json.Marshal(item)
72+
73+
fmt.Println("Returning item: ", string(item_marshalled))
74+
75+
//Returning response with AWS Lambda Proxy Response
76+
return events.APIGatewayProxyResponse{Body: string(item_marshalled), StatusCode: 200}, nil
77+
}
78+
79+
func main() {
80+
lambda.Start(Handler)
81+
}

0 commit comments

Comments
 (0)