サーバーレスWebAPI開発に入門できました

前回の記事の続きです。
go-swaggerを使うのをやめて、Ginというフレームワークを使う事で無事入門できました。

nns7.hatenablog.jp

Ginフレームワークの使い方はこちらの記事を参考にさせて頂きました。

selfnote.work

ソースコードを公開してます。参考になれば幸いです。

GitHub - nns7/serverless-api-go-tutorial

開発環境

DynamoDB Localをローカルにデプロイする

前回の記事ではローカルでのDynamoDBのテストにLocalStackを使っていましたが、調べたところAWSがDynamoDB Localというものを用意してくれているので、そちらを使うようにします。
コンピュータ上で DynamoDB をローカルでデプロイする - Amazon DynamoDB

公式にdocker-composeが解説されているため、そちらを参考に以下のように記述しました。
エンドポイントをhttp://dynamodb-local:8000とすればアクセスできます。

docker-compose.yml

version: '3'
services:
  aws-sdk-go-containter: 
    build: 
      context: .
      dockerfile: ./build/Dockerfile
    container_name: aws-sdk-go-containter
    depends_on:
      - dynamodb-local
    volumes:
      - "~/.aws:/root/.aws"

  # DynamoDB Local
  dynamodb-local:
    command: "-jar DynamoDBLocal.jar -sharedDb -optimizeDbBeforeStartup  -dbPath ./data"
    image: "amazon/dynamodb-local:latest"
    container_name: dynamodb-local
    ports: 
      - "8000:8000"
    volumes:
      - "./docker/dynamodb:/home/dynamodblocal/data"
    working_dir: /home/dynamodblocal

APIサーバーをローカルに立てる

公開しているソースコードはLambdaにデプロイするためのものですが、main.godb.goを以下のように書き換えることで、APIサーバーとしてローカルで実行できるようになります。

main.go

package main

import (
    "github.com/nns7/userapp"

    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()
    // ユーザー作成
    router.POST("/users", userapp.PostUsers)
    // ユーザー一覧の取得
    router.GET("/users", userapp.GetUsers)
    // ユーザーの更新
    router.PUT("/users/:user_id", userapp.PutUser)
    // ユーザーの削除
    router.DELETE("/users/:user_id", userapp.DeleteUser)
    // ユーザーの検索
    router.GET("/users/search", userapp.SearchUser)
    router.Run()
}

db.go

(省略)

func init() {
    usersTable = "local_users"
    if usersTable == "" {
        log.Fatal("missing env variable: DYNAMO_TABLE_USERS")
    }

    dbEndpoint := "http://dynamodb-local:8000"
    sess := session.Must(session.NewSessionWithOptions(session.Options{
        Profile:           "local",
        SharedConfigState: session.SharedConfigEnable,
        Config: aws.Config{
            Endpoint:   aws.String(dbEndpoint),
            DisableSSL: aws.Bool(true),
        },
    }))
    gdb = dynamo.New(sess)
}

書き換えたらTerminal上で以下のコマンドを実行してください。DynamoDB Localにはテーブルが存在しないため、合わせてテーブルを作成します。

$ aws dynamodb create-table --table-name 'local_users' --endpoint-url "http://dynamodb-local:8000" \
--attribute-definitions '[{"AttributeName":"user_id","AttributeType": "S"}]' \
--key-schema '[{"AttributeName":"user_id","KeyType": "HASH"}]' \
--provisioned-throughput '{"ReadCapacityUnits": 5,"WriteCapacityUnits": 5}'
$ go run cmd/lambda/main.go

APIサーバーにリクエストを投げてみる

Chrome拡張の『Talend』を使ってHTTPリクエストを投げていきます。

ユーザーの登録

{
  "user_id": "001",
  "name": "gopher"
}

Responseに200 OKと表示されたら成功です。

ユーザーの一覧

[
  {
    "user_id": "001",
    "name": "gopher"
  }
]

さきほど登録したユーザーが取得できましたね。
別のユーザーをもう一つ登録してみて、GETメソッドで取得できるユーザーが増える事を確認してみてください。

ユーザーの更新

{
  "name": "gopher2"
}

GETメソッドでユーザーの一覧を取得すると、nameが変わっている事が確認できます。

ユーザーの削除

{
  "message": "user has been deleted"
}

GETメソッドでユーザーの一覧を取得すると削除された事が確認できます。

参考

[Golang/Go言語]GinフレームワークでAPI開発2~CRUDの実装~ | セルフノート
DynamoDB×Go連載#1 GoでDynamoDBでおなじみのguregu/dynamoを利用する | フューチャー技術ブログ
ginをMVCで設計している時にコントローラのテストを書く
AWS LambdaでGolangのWebフレームワークGinを利用してみた | デロイト トーマツ ウェブサービス株式会社(DWS)公式ブログ
DynamoDB をローカルで使う
aws cli で DynamoDB を使う - Qiita