はじめに
この記事では、Go(guregu)を用いてLambdaを介し、DynamoDBとのデータのやりとりを紹介します。
lambdaを動かしてみよう
2023/12/31にLambdaのGoランタイムがサポート終了となりますが、buildしてLambdaへ渡すため、ランタイムは必要ありません。
まずは簡単なコードから実行してみましょう。任意のディレクトリで以下のコマンドを実行して、プロジェクトを作成します。
まずは簡単なコードから実行していきましょう。
任意のディレクトリで
$ mkdir go-lambda-test
$ cd go-lambda-test
$ go mod init test
上から順に実行し、プロジェクトを作成していきます。
ディレクトリ直下にmain.goを作成し、以下のコードを記述します。
package main
import (
"context"
"github.com/aws/aws-lambda-go/lambda"
)
// ハンドラ関数を定義
func handler() (string, error) {
return "Hello, lambda", nil
}
func main() {
// Lambdaのハンドラを起動
lambda.Start(handler)
}
以上記述できたらbuildしてzipファイルへと変換します。
$ GOOS=linux GOARCH=arm64 go build -o bootstrap main.go
$ zip test.zip bootstrap
また、実行ファイル名はbootstrapにするという命名規則がありますので、守るようにしてください。Lambdaのコンソールから以下の設定で関数を作成します。
ランタイム: Amazon Linux 2023
アーキテクチャ: arm64
zipファイルをアップロードし、テストを行い成功すれば
"Hello, lambda"
が返ってくると思います。
DynamoDB
次に、DynamoDBを操作してみましょう。DynamoDBのコンソールからテーブルを作成します。テーブルにはName
, Age
, Hobby
の項目を持つことにしました。
注意点として、LambdaからDynamoDBにアクセスするためにはIAMロールを設定する必要があります。今回は以下のロールを設定しました。
AmazonDynamoDBFullAccess
AWSLambdaDynamoDBExecutionRole
PUT
package main
import (
"context"
"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/guregu/dynamo"
)
type UserInfo struct {
Name string `dynamo:"name"`
Age int `dynamo:"age"`
Hobby string `dynamo:"hobby"`
}
// ハンドラ関数を定義
func handler(ctx context.Context, userInfo UserInfo) (string, error) {
db := dynamo.New(session.New(), &aws.Config{
Region: aws.String("us-east-1"),
})
table := db.Table("Test")
err := table.Put(userInfo).Run()
if err != nil {
fmt.Println(err)
return "Put request failed", err
}
return "Put request successed", nil
}
func main() {
// Lambdaのハンドラを起動
lambda.Start(handler)
}
以上記述できたら先ほどと同じように、buildしてzipファイルへと変換します。
$ GOOS=linux GOARCH=arm64 go build -o bootstrap main.go
$ zip test.zip bootstrap
テストのイベントJSONを以下のように記述しテストを行います。
{
"name": "Shinji",
"age": 16,
"hobby": "Eva"
}
このように記述しテストを行うと
"Put request successed"
が返り、DynamoDBのテーブル内に書き込まれていることが確認できます。
GET
package main
import (
"context"
"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/guregu/dynamo"
)
type UserInfo struct {
Name string `dynamo:"name"`
Age int `dynamo:"age"`
Hobby string `dynamo:"hobby"`
}
type UserName struct {
Name string `dynamo:"name"`
}
// ハンドラ関数を定義
func handler(ctx context.Context, userName UserName) ([]UserInfo, error) {
db := dynamo.New(session.New(), &aws.Config{
Region: aws.String("us-east-1"),
})
table := db.Table("Test")
var result []UserInfo
err := table.Get("name", userName.Name).All(&result)
if err != nil {
fmt.Println(err)
return nil, err
}
return result, nil
}
func main() {
// Lambdaのハンドラを起動
lambda.Start(handler)
}
テストのイベントJSONを
{
"name": "Shinji"
}
こちらを渡します。
すると
[
{
"Name": "Shinji",
"Age": 16,
"Hobby": "Eva"
}
]
データの取得に成功しました。
Update,Deleteも似たような記述で可能なので、やってみたい方はgureguの作者様が記事を書いてるので参考にしてみてください。
まとめ
少し興味があり、手を出してみましたがgureguを利用した所感としてはRDBでいうところのORMに近しいと思いました。
興味があればぜひ記事を参考に利用してみてください。
APIGateWayからリクエストを受け取る方式も気が向けば記事にしようと思います。
記事内に間違いなどございましたら教えていただけると幸いです。
追記
APIGateWayを介す場合SDKで書いた方が簡単そうですね。
参考
guregu [気楽にDynamoDBを使おう] https://qiita.com/guregu/items/2e9ac305791935b86f5d
[Go-lambda] https://pkg.go.dev/github.com/aws/aws-lambda-go/lambda