Go言語で実装したNetlify Functionsをローカル環境で動かす

本記事では、Go言語で実装したNetlify Functionsを
ローカル環境での動作確認する方法を記載します。

おそらくawslambdaをローカル環境で動作確認する方法と
同等かと思いますが、自分用のメモとしても残しておきたいと思います。

# はじめに

既に[運営の方で](https://www.netlify.com/docs/functions/#go-lambda-functions)Go言語で実装したfunctionをデプロイする記事が
公開されていますが、ローカル環境で動作させる方法については、
詳細の記事がない状態だったため、本記事を作成しました。

また、Netlifyという非常にデプロイまでが簡単なサービスを
使えたおかげで、

- lambdaの実装方法
- Go言語の勉強

を行うことができました。本記事を通して、
上記の勉強に踏み出せなかった方への手助けとなればと思います。

もし、間違いやお気付きの点等ありましたら、
ご指摘いただけると幸いです。m(_ _)m

# Netlifyについて

## Netlifyとは

ざっくり触れていきます。

- 静的サイトホスティングサービス
- GitHubやGitLabといったサービスのリポジトリを参照してのデプロイが可能
- 無料でできることが多い

詳しくは記事を参照いただくと幸せになれると思います。

- [【Qiita】高機能ホスティングサービスNetlifyについて調べて使ってみた](https://qiita.com/TakahiRoyte/items/b7c4d1581df1a17a93fb)

## Functionsとは

Netlify Functionsは、
Netlifyのサービスの中の1つと思っていただいた方が
イメージつきやすいかと思います。

ざっくりと説明すると以下になります。

- 関数（lambda)だけ実装すればWebAPI化可能
- 使用可能な言語は以下
    - Node.js(JavaScript)
    - Go言語
- Netlifyにデプロイされると、裏でAWSにデプロイされる
    - 10秒以上の処理はタイムアウトとなる
        - ソースは[こちら](https://www.netlify.com/docs/functions/#custom-deployment-options)
        - 重い処理をさせることはできないが、Slackと連携させるWebAPIとしては十分

詳しくはこちらのスライドを参照していただけると幸いです。

- [【speakerdeck】NetlifyでFaaSに入門する / netlify-functions](https://speakerdeck.com/mottox2/netlify-functions)

# インストール

ローカル環境で動かすにあたって、
必ず以下をインストールする必要があります。

- [Go言語のインストール]((http://golang.jp/install))
- [Docker for Macのインストール](https://docs.docker.com/docker-for-mac/install/)
    - 以下のSAMCLIを動作させるために必要となります
- SAM CLIのインストール
    - [こちら](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/sam-cli-requirements.html)参照

# ローカル開発環境での動作確認

Netlify運営の方で[サンプル](https://github.com/netlify/aws-lambda-go-example)を用意してくれています。

そのサンプルを元にローカル環境で開発するための
設定を追加した以下リポジトリを用意しました。

- [go-netlify-functions-sample](https://github.com/zakizaki-ri9/go-netlify-functions-sample)

上記リポジトリを元に
ローカル環境で動作させるための手順を記載します。

## 手順

### 1.`go build`の実施

本リポジトリでは、`source`配下の`hello`と`json`という
2つのfunctionを実装しようとしています。
これらをそれぞれビルドし、`functions`配下に配置します。

イメージとしては以下のような感じです。

```bash:イメージ
.
├── functions
│   ├── hello
│   └── json
├── source
│   ├── hello
│   │   └── main.go
│   └── json
│       └── main.go
```

コマンドは以下を使用します。


```bash:ビルドコマンド
GOOS=linux GOARCH=amd64 go build -o ./functions/hello ./source/hello
GOOS=linux GOARCH=amd64 go build -o ./functions/json ./source/json
```

### 2.`template.yml`の作成

ローカル環境では`SAM CLI`というツールで動作させますが、
[template.yml](https://github.com/zakizaki-ri9/go-netlify-functions-sample/blob/master/template.yml)にパス等の設定情報を記載する必要があります。

```yml:template.yml（一部変更）
# 省略
Resources:
  〜Function:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: #要変更: バイナリを配置するパス（今回だと"functions/"）
      Handler: #要変更: バイナリ名（今回だと"hello" or "json"）
      Runtime: go1.x
      Tracing: Active
      Events:
        CatchAll:
          Type: Api
          Properties:
            Path: #要変更: functionのパス
            Method: GET #要変更: POSTなど
      Environment:
        Variables:
          PARAM1: VALUE
# 省略
```

functionを追加したい場合は`〜Function:`のブロックを追加し、
以下**#要変更**部分を変更しましょう。

GET以外にPOSTなどにも対応させたい場合は、
`Properties`のブロックを追加し、`Method`の値を変更すればOKです。

### 3.動作確認

Docker for Macを起動します。
（以下のようにrunning状態になっていればOKです。)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/140704/a36bec99-b873-b186-45f1-e533f62d0e40.png)

カレントディレクトリを`go-netlify-functions-sample`にして、
`sam local start-api`を実行します。

```bash:実行例
$ pwd
/省略/go-netlify-functions-sample
$ sam local start-api
2018-12-01 17:10:10 Mounting JsonFunction at http://127.0.0.1:3000/json [GET]
2018-12-01 17:10:10 Mounting HelloFunction at http://127.0.0.1:3000/hello [GET]
2018-12-01 17:10:10 You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions changes will be reflected instantly/automatically. You only need to restart SAM CLIif you update your AWS SAM template
2018-12-01 17:10:10  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
```

上記の状態になったら、動作確認可能な状態となります。

- `http://127.0.0.1:3000/hello`
- `http://127.0.0.1:3000/json`

上記URLをブラウザから実行し、
`hello`と`json`が動作するか試してみます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/140704/1053f26f-39bd-a5dd-f578-d6cf3578c43a.png" width=500px>

<img src="https://qiita-image-store.s3.amazonaws.com/0/140704/5829ee19-4941-586b-0695-83bc1e89a62e.png" width=500px>

ソースコードで記述した内容が返却されていることを確認できます。

# おわり

今回紹介した以下リポジトリは、
自分でNetlify FunctionsをGo言語で書くための
テンプレートとして使用しています。

もしよろしければ、
fork / Downloadして使用してみてください。

※何も変更せずとも、Netlify Functionsとしてデプロイも可能です。

- [go-netlify-functions-sample](https://github.com/zakizaki-ri9/go-netlify-functions-sample)