はじめに
去年のRe:Inventで「来年の早い時期にLambdaがGoに対応するよ!」なんてアナウンスされた時は、来たかっ!という気持ちになりました。
首を長くして待っていたら、本日サポートしたと発表があったので早速試してみました。
デモdemo
普段Node.jsを使ってLambda+DynamoDBの構成を組んでいるので、今回もDynamoDBを絡めてデモってみました。
公式が出している記事を参考にしていただければいいのですが、
現時点でサポートしているバージョンは 1.x
です。
基本的なデプロイの流れは
- Go書く
- Linux用にビルドする
- zipでアップロード
という流れになると思います。
Go書く
基本形は下記のような感じです。
package main
import (
"github.com/aws/aws-lambda-go/lambda"
"fmt"
)
type Response struct {
Message string `json:"message"`
Ok bool `json:"ok"`
}
func Handler() (Response, error) {
// 処理部分
}
func main() {
lambda.Start(Handler)
}
lambda.Start(Handler)
でLambdaの処理を実行します。
なんか少し違和感があるのは私だけでしょうか…
んで、 Handler
の中に実際の処理を書いていく感じになります。
DynamoDB(GetItem, PutItem, Query)
aws-sdk for goを使ってDynamoDBにリクエストを送っていきます。
上記のソースコードに追記したのが下記になります。
package main
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-lambda-go/lambda"
"fmt"
)
type Response struct {
Message string `json:"message"`
Ok bool `json:"ok"`
}
func Handler() (Response, error) {
// session
sess, err := session.NewSession()
if err != nil {
panic(err)
}
svc := dynamodb.New(sess)
// GetItem
getParams := &dynamodb.GetItemInput{
TableName: aws.String("go-demo"),
Key: map[string]*dynamodb.AttributeValue{
"id": {
S: aws.String("1"),
},
},
}
getItem, getErr := svc.GetItem(getParams)
if getErr != nil {
panic(getErr)
}
fmt.Println(getItem)
// PutItem
putParams := &dynamodb.PutItemInput{
TableName: aws.String("go-demo"),
Item: map[string]*dynamodb.AttributeValue{
"id": {
S: aws.String("2"),
},
"name": {
S: aws.String("hoge"),
},
},
}
putItem, putErr := svc.PutItem(putParams)
if putErr != nil {
panic(putErr)
}
fmt.Println(putItem)
// Query
queryParams := &dynamodb.QueryInput{
TableName: aws.String("go-demo"),
KeyConditionExpression: aws.String("#ID=:id"),
ExpressionAttributeNames: map[string]*string{
"#ID": aws.String("id"),
},
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":id": {
S: aws.String("1"),
},
},
}
queryItem, queryErr := svc.Query(queryParams)
if queryErr != nil {
panic(queryErr)
}
fmt.Println(queryItem)
return Response{
Message: fmt.Sprintln(getItem.Item),
Ok: true,
}, nil
}
func main() {
lambda.Start(Handler)
}
GetItemで返ってくるレスポンスはこんな感じ
{
Item: {
id: {
S: "1"
},
name: {
S: "test"
}
}
}
Queryで返ってくるレスポンスはこんな感じ
{
Count: 1,
Items: [{
id: {
S: "1"
},
name: {
S: "test"
}
}],
ScannedCount: 1
}
ビルドして、zipに固める
$ go build -o main.go
$ zip deployment.zip main
linux用にビルドしないといけないので、macの方は下記を実行してからzipに固めてください。
$ GOOS=linux go build -o main
Lambdaにデプロイする
Lambdaのコンソールから新しく関数を作成して、ランタイムを Go 1.x
を選択します。
アタッチするロールには今回はDynamoDB関係の権限も忘れずに。
関数が作成されたら、先ほど作成したZipファイルをアップロードすれば完了です。
これでGoを使ってDynamoDBのデータを操作できるぞ!
あとがき
正直Go言語はほとんど触ったことなかったので、ソースコードはきったねぇと思いますがご了承ください。
Node.jsの感覚で実装したら動いたって感じです…(汗)
Node.jsで実装していると「シングルスレッドじゃあしんどいな…」と感じている時もあったりします。
Go言語はNode.jsと違って並列処理に長けているので、ケースバイケースで「Node.jsよりもGoの方がよいんでは?」となりそうなので、今のうちにGo言語に慣れておかなければと実感しました。
ではまた!