Netlify FunctionsをGoで記述する

# Netlify FunctionsをGoで書く
AWS lambdaを使う感覚でFaasを使いたい場面がありました。
ただ、AWS lambdaを使うのは少し荷が重い(従量課金制なので万一ミスしたときが怖い)ので、Netlify Functions上でGoを動かしました。

## 手順

1. <a href="#procedure1">NetlifyとGitのホスティングサービス上のリポジトリを紐づける</a>
1. <a href="#procedure2">紐づけたリポジトリのSitesでFunctionsのディレクトリを設定</a>
1. <a href="#procedure3">GoでFunctionを作成</a>
1. <a href="#procedure4">Functionsのビルドの設定(Netlify.toml、Makefileの記述)</a>
1. pushを行い，Functionsが起動しているかを確認する

<h3 id="procedure1">リポジトリの紐づけ</h3>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313441/d289bb8e-4b05-e519-fc04-8e40158b5a5a.png)
New Site From GitのボタンからGitのホスティングサービスから連携するGitホスティングサービスを選択する画面に飛ぶので、そこから紐づけたいリポジトリがあるGitホスティングサービスを選択します。
今回は、GitHubを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313441/cea5d9a4-ceb3-135b-061c-a7669dc9d81a.png)
次の画面で、紐づけたいリポジトリを選択します。
リポジトリが存在しないときは、`Configure the Netlify app on *****(ホスティングサービス名)`のリンクを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313441/c3afd95e-31d4-06a4-783c-26ff3eca7724.png)

NetlifyにGithubアカウントでログインして紐づけるリポジトリを選択します。
選択するとNetlify側で紐づけたいリポジトリが表示されていると思うので、そのリポジトリを選択します。

次のページBuild commandの設定やデプロイするブランチの画面が出てくるので、適当に設定して `Deploy Site` のボタンでサイトをデプロイします。

<h3 id="procedure2">Functionsのディレクトリの設定</h3>
一応、netlify.tomlでも設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313441/cfff0ed9-03fe-80ab-321a-77c421eadd80.png)
作成したSiteの中で、Functionsの設定をします。
Site settings から Functionsの項目を選択します。
ここでのデフォルトは`netlify/functions`になっていると思うので、Functionsのディレクトリを適宜変えてください。
僕は、いつも`functions`で設定しています。

<h3 id="procedure3">GoでFunctionを作成</h3>
Goのモジュールの依存性を解決するためにリポジトリのルートで`go mod init`を叩いて、go modを作っておきます。
さらに、Functionsを使う際に利用するモジュールを`go get`で取得します。

`go get github.com/aws/aws-lambda-go`

で必要なモジュールが取得できます。

以下がGoで書いた簡単なFunctionsです。

```golang:go-functions/hello/main.go
package main

import (
	"net/http"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func handler(request events.APIGatewayProxyRequest) (*events.APIGatewayProxyResponse, error) {
	// GET以外はBad Request
	if request.HTTPMethod != http.MethodGet {
		return &events.APIGatewayProxyResponse{
			StatusCode: 400,
			Body:       "Bad Request",
		}, nil
	}

	return &events.APIGatewayProxyResponse{
		StatusCode: 200,
		Body:       "Hello Netlify Functions",
	}, nil
}

func main() {
	// Start Handler
	lambda.Start(handler)
}
```

<h3 id="procedure4">ビルドの設定</h3>
リポジトリのルートに`netlify.toml`と`Makefile`を作成します。
netlify.tomlは、netlifyでビルドの際のコマンドやFunctionsの環境の設定ができます。

```conf:netlify.toml
[build]
  base = "/"
  command = "make build"
  publish = "/dist"
  functions = "/functions"

[build.environment]
  GO_VERSION = "1.14.5"
```

Makefileで実際のビルドの設定をしていきます。

```make:Makefile
build:
    mkdir -p functions
    go get ./go-functions/hello/...
    go install ./go-functions/hello/...
    go build -o ./functions/hello ./go-functions/hello/main.go
```

これで、ビルドの設定が完了です。

### pushを行い，Functionsが起動しているかを確認する
後は、デプロイするブランチにpushを行い `https://{{ホスト名}}/.netlify/functions/{{関数の名前}}`にアクセスする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313441/efaa90b5-53a8-c6e5-4fe6-340885c3ea15.png)

こんな感じでデプロイできました。

Netlify Functionsのlambdaの時間制限が10秒程度なので、重い処理や待ちが入る処理は厳しいですが、ちょっとしたものを作る時は結構役に立ちそうです。

### 参考
* https://docs.netlify.com/functions/build-with-go
* https://github.com/netlify/aws-lambda-go-example