LoginSignup
24
7

More than 5 years have passed since last update.

AWSLambdaがGo言語に対応したのでDynamoDBと絡ませながらデモってみた

Last updated at Posted at 2018-01-16

はじめに

去年のRe:Inventで「来年の早い時期にLambdaがGoに対応するよ!」なんてアナウンスされた時は、来たかっ!という気持ちになりました。
首を長くして待っていたら、本日サポートしたと発表があったので早速試してみました。

デモdemo

普段Node.jsを使ってLambda+DynamoDBの構成を組んでいるので、今回もDynamoDBを絡めてデモってみました。

公式が出している記事を参考にしていただければいいのですが、
現時点でサポートしているバージョンは 1.x です。
基本的なデプロイの流れは
1. Go書く
2. Linux用にビルドする
3. 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関係の権限も忘れずに。
スクリーンショット 2018-01-16 15.05.24.png

関数が作成されたら、先ほど作成したZipファイルをアップロードすれば完了です。
スクリーンショット 2018-01-16 15.06.08.png

これでGoを使ってDynamoDBのデータを操作できるぞ!

あとがき

正直Go言語はほとんど触ったことなかったので、ソースコードはきったねぇと思いますがご了承ください。
Node.jsの感覚で実装したら動いたって感じです…(汗)

Node.jsで実装していると「シングルスレッドじゃあしんどいな…」と感じている時もあったりします。
Go言語はNode.jsと違って並列処理に長けているので、ケースバイケースで「Node.jsよりもGoの方がよいんでは?」となりそうなので、今のうちにGo言語に慣れておかなければと実感しました。

ではまた!

24
7
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
24
7