LoginSignup
19
11

More than 5 years have passed since last update.

AWS Lambda, API Gateway, DynamoDB, Golang でREST APIを作る

Posted at

 はじめに

GolangとAWSの勉強がてらに、DynamoDB+Lambda+APIGatewayつかってREST APIをつくりました。

qiita.png

 参考

DynamoDB

今回は簡易的にUserIDとUserNameだけ含むユーザーテーブルを用意します。
テーブルの作り方は”初めてのサーバーレスアプリケーション開発 ~DynamoDBにテーブルを作成する~”を参考にしてください

スクリーンショット 2018-12-11 20.10.14.png

Lambda

まずLambdaにDynamoDBへのアクセス権を与えるため、IAMロールを作成しなくてはいけないので
1. [IAM] -> [Roles] -> [Create role] -> AWS servicesからLambdaを選択し[Next Permissions] -> [AmazonDynamoDBFullAccess][AWSLambdaBasicExecutionRole]を選択し→[Next Tags][Next Review][Create role]

  1. Lambdaのメニューから[Create function]を選択して以下のようにLambdaを作成
    スクリーンショット 2018-12-11 20.24.46.png

  2. AWSのGoのSDKをインストール

$ 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

スクリーンショット 2018-12-11 20.43.09.png

go.getuser.go
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)
}

以下のようにテストすると
スクリーンショット 2018-12-11 20.48.22.png

帰ってきた!:santa_tone2:
スクリーンショット 2018-12-11 20.49.06.png

/user/ -POST-

BodyパラメータからIDとUserNameを取得してDynamoDBに書き込む

createuser.go
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

deleteuser.go
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.godeleteuser.goに関しても同様にzipにしてアップロードしてください:bicyclist:

API Gateway

  1. [+Create API] から適当に新しいAPIを作成 スクリーンショット 2018-12-11 20.59.49.png

/user/{id} - GET

  1. [Actions] -> [Create Resource]から スクリーンショット 2018-12-11 21.01.53.png
  2. また[Create Resource]から スクリーンショット 2018-12-11 21.03.48.png
  3. [Create Method]からGETを選択して、さっき作ったLambdaを選択 スクリーンショット 2018-12-11 21.05.42.png
  4. [Integration Request] -> [Mapping Templates] を順に選択して、以下のように設定する スクリーンショット 2018-12-11 21.09.15.png
  5. [Test:zap:]からパスパラメータにidを指定して実行すると、 スクリーンショット 2018-12-11 21.10.48.png 帰ってきた!:santa_tone1:

/user/ - POST

Request Bodyにidとusernameを入力して実行:zap:

スクリーンショット 2018-12-11 21.18.55.png

おわり

以上、簡単にLambda+DynamoDB+API GatewayでREST APIつくってみました!
DynamoDBからのGetItemOutputをjsonで返すやりかた分かる人いたら教えてほしいです。:pray:

19
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
11