API Gateway + Lambda を使って何かしたいが、 node とか Python はちょっとという感じで調べていたら apex というやつを使えば Golang で Lambda 関数が書けることがわかったのでそのメモ

下準備

  • apex のインストール
  • AWS の access key などの用意
    • 環境変数ないしは ~/.aws/ ファイルで設定
  • Go のインストール

前2つは apex のページを参考に。Goに関しても公式を見ればすぐに見つかるので各環境に合わせてインストール

AWS の access key などの設定に関して、自分は環境変数で指定した

# .bashrc

export AWS_ACCESS_KEY_ID="<AWS account access key>"
export AWS_SECRET_ACCESS_KEY="<AWS account secret key>"
export AWS_REGION="ap-northeast-1"

Lambda 関数の作成

どこでもいいが自分は GOPATH の下に workspace を作った

$ cd ~/go/src/github.com/mmyoji
$ mkdir apex-sample
$ cd apex-sample
$ apex init 
>  Project name: apex-sample

最初は ./functions/hello/index.js が生成されているが使わないので消したあと、 ./functions/hello/main.go などを作る

./functions/<Lambda 関数名>/main.go としておけばよさそうなので、 Lambda 関数名にしたい directory 名にするとよさそう

API のインターフェースと apex コードの対応

例えば API Gateway 側に POST でリクエストを送るとする

Body は json で以下のようなデータを送る

{
  "id":  1,
  "url": "http://example.com"
}

送信した URL のページをクロールして、コンテンツ( body ) を返すとする

{
  "id": 1,
  "body": "xxxxxx"
}

go-apex を使った実装例

package main

import (
	"encoding/json"

	"github.com/apex/go-apex"
)

type Request struct {
	id  int    `json:"id"`
	url string `json:"url"`
}

type Response struct {
	id   int    `json:"id"`
	body string `json:"body"`
}

func main() {
	apex.HandleFunc(func(event json.RawMessage, ctx *apex.Context) (interface{}, error) {
		var req Request
		var res Resposne

		if err := json.Unmarshal(event, &req); err != nil {
			return nil, err
		}

		res.id = req.id

		// Get the body of the page
		bd, err := getBody(req.url)
		if err != nil {
			return nil, err
		}

		res.body = bd

		return res, nil
	})
}

// 省略
func getBody(url string) (string, error) {
	// TODO
}

上記のようなコードを(一部省略しているが)書いて、 API Gateway に乗せれば動く(はず)

local でテスト

# "event" でラップする必要がある
$ echo '{"event":{"id":1,"url":"http://example.com"}}' | go run ./functions/hello/main.go

# or

# "event" で囲む必要はなく、期待する request body をそのまま json ファイルなどにして redirect で渡す
$ apex invoke hello < req.json

これでうまくいけば API Gateway でも動く(はず)

Deploy

$ apex deploy で終わり。簡単

API Gateway の設定

特に何も考えず、ポチポチしていれば終わる

  1. API の作成
  2. メソッドの作成
  3. 統合タイプ: Lambda 関数, Lambda リージョン: <上記の AWS 設定で指定したregion>, Lambda 関数: 今回作成した関数

で作成でおk

あとは細々した設定をしたければ別途行う。

request の検証を JSON Schema でできたりするので、「モデル」という項目などで設定すると better

あとはテストしてみたりして大丈夫そうなら、 アクション dropdown から API のデプロイ という項目を選び、該当する API をデプロイします。

URL が発行されるのでそこに対して request を飛ばしてうまく動けば :ok_woman:

それ以降の流れ

  1. 該当リポジトリで開発
  2. apex invoke xxx などで確認
  3. apex deploy

:smile:

おわりに

今回 apex 以外は特に調べたりせず雑に開発したが、簡単に実行まで行けてよかった

最近は GCP の方が人気があって AWS ばかり触ってると肩身が狭いが、気軽に使えるので選択肢としてあってもいいのかな?と思う