はじめに
GolangとAWSの勉強がてらに、DynamoDB+Lambda+APIGatewayつかってREST APIをつくりました。
参考
DynamoDB
今回は簡易的にUserIDとUserNameだけ含むユーザーテーブルを用意します。
テーブルの作り方は”初めてのサーバーレスアプリケーション開発 ~DynamoDBにテーブルを作成する~”を参考にしてください
Lambda
まずLambdaにDynamoDBへのアクセス権を与えるため、IAMロールを作成しなくてはいけないので
1. [IAM] -> [Roles] -> [Create role] -> AWS servicesからLambdaを選択し[Next Permissions] -> [AmazonDynamoDBFullAccess]と[AWSLambdaBasicExecutionRole]を選択し→[Next Tags]→[Next Review]→[Create role]
$ go get -u -v github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute
$ go get -u -v github.com/aws/aws-lambda-go/lambda
$ go get -u -v github.com/aws/aws-sdk-go/aws
$ go get -u -v github.com/aws/aws-sdk-go/aws/session
$ go get -u -v github.com/aws/aws-sdk-go/service/dynamodb
もしくは
$ go get -u -v github.com/aws/aws-sdk-go/...
ちなみに -u のフラグで最新のパッケージがインストールできて、-v でインストール経過が確認できます。
/user/{id} - GET
パスパラメータのidと一致するUserIDを持つユーザーデータを返します。
コードはローカルで編集してzipにしてLambdaにアップロードします。
$ GOOS=linux go build -o main
$ zip deployment.zip main
package main
import (
"fmt"
"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"
)
type User struct {
UserID string `json:"userid"`
USerName string `json:"username"`
}
type Request struct {
ID string `json:"id"`
}
type Response struct {
Data string `json:"body"`
}
func Handler(request Request) (Response, error) {
sess, err := session.NewSession()
if err != nil {
panic(err)
}
svc := dynamodb.New(sess)
getParams := &dynamodb.GetItemInput{
TableName: aws.String("User"),
Key: map[string]*dynamodb.AttributeValue{
"UserID": {
S: aws.String(request.ID),
},
},
}
getItem, getErr := svc.GetItem(getParams)
if getErr != nil {
panic(getErr)
}
return Response{
Data: fmt.Sprintln(getItem),
}, nil
}
func main() {
lambda.Start(Handler)
}
/user/ -POST-
BodyパラメータからIDとUserNameを取得してDynamoDBに書き込む
package main
import (
"fmt"
"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"
)
type User struct {
UserID string `json:"userid"`
USerName string `json:"username"`
}
type Response struct {
Data string `json:"message"`
}
type Request struct {
ID string `json:"id"`
UserName string `json:"username"`
}
func Handler(request Request) (Response, error) {
sess, err := session.NewSession()
if err != nil {
panic(err)
}
svc := dynamodb.New(sess)
putParams := &dynamodb.PutItemInput{
TableName: aws.String("User"),
Item: map[string]*dynamodb.AttributeValue{
"UserID": {
S : aws.String(request.ID),
},
"UserName": {
S : aws.String(request.UserName),
},
},
}
putItem, putErr := svc.PutItem(putParams)
if putErr != nil {
panic(putErr)
}
return Response{
Data: fmt.Sprintln(putItem),
}, nil
}
func main() {
lambda.Start(Handler)
}
/user/{id} DELETE
package main
import (
"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"
)
type User struct {
UserID string `json:"userid"`
USerName string `json:"username"`
}
type Request struct {
ID string `json:"id"`
UserName string `json:"username"`
}
func Handler(request Request) error {
sess, err := session.NewSession()
if err != nil {
panic(err)
}
svc := dynamodb.New(sess)
deleteParams := &dynamodb.DeleteItemInput{
TableName: aws.String("User"),
Key: map[string]*dynamodb.AttributeValue{
"UserID": {
S: aws.String(request.ID),
},
},
}
if _, err := svc.DeleteItem(deleteParams); err != nil{
panic(err)
}
return nil
}
func main() {
lambda.Start(Handler)
}
createuser.goとdeleteuser.goに関しても同様にzipにしてアップロードしてください
API Gateway
/user/{id} - GET
- [Actions] -> [Create Resource]から
- また[Create Resource]から
- [Create Method]からGETを選択して、さっき作ったLambdaを選択
- [Integration Request] -> [Mapping Templates] を順に選択して、以下のように設定する
- [Test
]からパスパラメータにidを指定して実行すると、
帰ってきた!
/user/ - POST
Request Bodyにidとusernameを入力して実行
おわり
以上、簡単にLambda+DynamoDB+API GatewayでREST APIつくってみました!
DynamoDBからのGetItemOutputをjsonで返すやりかた分かる人いたら教えてほしいです。