Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

去年の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言語に慣れておかなければと実感しました。

ではまた!

is_ryo
(IoTチョットワカル)フロントエンドエンジニア。 Vue.js / AWS / GraphQL / Serverless
https://is-ryo.com
acall
「Life in Work and Work in Life for Happiness」をビジョンに掲げ、様々なワークスペース、ハードウェア、ソフトウェアを統合して"はたらく"の体験を向上するWorkstyleOSを通じ、暮らしと仕事の幸福度の最大化と追求します。
https://www.acall.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした