【API作るよ】Serverless FrameworkとSAMを比較してみる

AWSでAPIを作りましょう(唐突)
面倒なことはフレームワークに丸投げしましょう。

# TL;DR
- AWSでサーバレスアーキテクチャ構築するときに代表的なフレームワークであるServerless FrameworkとSAMを比較してみたよ
- 筆者の判定だとServerless Frameworkに軍配かな
- SAMはプラグインがやや少ないのと癖が強いから今後に期待！

# 導入
サーバサイドエンジニアをやっているとAWSでAPI構築しましょうっていう案件に参画することがあるかもしれません。
そんなときに、ゼロから作ろうって話になることも……あるかもしれません。

で、だいたいそのときにAWSで

- Lambda
- DynamoDB
- API Gateway

とかそれぞれの知識が必要になってくるわけですが、一つ一つ個別に作ってるとかなり大変です。
Serverless FrameworkやSAMのようなフレームワークを使えば、そこらへんを設定ファイル一枚、コマンド一発で構築まで全部やってくれます。

# Serverless Frameworkについて
この手のフレームワークのデファクトスタンダード……とまで言うと言いすぎかもしれませんが、この手のフレームワークにしては非常に「枯れて」いて、機能も充実しています。
APIを構築する場合……というかサーバレス環境を構築する場合、
「あるURIにPOST投げるとDynamoDBに要素がPUTされる」
みたいな機能を作ることになると思いますが、いちいち試すためにデプロイするのも面倒ですから、ローカルでDynamoDBを動かして機能を試してみたいところですよね。

そんなときローカルでサクッと動かせるというのは結構重要です。

詳細はこちらを参照してください(丸投げ)
[Serverless アプリケーションをローカルで開発する](https://qiita.com/noralife/items/e36621ddd0e5b8ff4447)
このとおりに作れば大丈夫です。

……丸投げが酷すぎるので、少し補足します。

Serverless FrameworkはNode.js系のプラグインが非常に充実していて、上記の記事にもあるように

```
serverless-dynamodb-local
```

のようなプラグインを導入するとかなり気軽にローカルでDynamoDBの環境を構築することができます。
後述しますが、SAMを使う場合だともう少し複雑になります。

【以下余談】
S3との連携プラグインも存在していますが……
https://www.npmjs.com/package/serverless-s3-local

LambdaをPythonで構築する場合、ちょっと微妙です。
ローカルでの構築例がgithubにありますが……
https://github.com/ar90n/serverless-s3-local/blob/master/example/simple_event_python/handler.py

読んで頂くとわかるように、「ファイル書き込むだけ」的なコードになっており、ローカルでの動作確認という用途としては……少々残念です。
【余談ここまで】

# SAMについて
真打ち、AWS公式のフレームワークです。

みんな大好きVisual Studio Code向けに公式提供されているAWS Toolkitと連携してます。
![スクリーンショット 2019-08-16 15.04.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247157/73da9992-4bf7-6e6b-20a6-7b32cf406b7b.png)
Pycharm版もあるぞ。

Serverless Frameworkがコマンド一発でデプロイできるのと比較して、少しステップは多いですがVisual Studio CodeのGUIからポチポチとクリックでデプロイができ、これはこれで便利です。

しかもローカル実行やデバッグもできるスグレモノ。
![sam-configure-and-run-still-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247157/8a003e1e-24a8-e9a7-bc10-3acc0c09b403.png)
(画像は公式のREADMEより)

これはもうSAMを選ぶしか無いのでは？
と言いたいところですが……

実際の構築をざっとお読みください。
こちらの記事が非常にわかりやすいです(再度丸投げ)
[Serverless アプリケーションをローカルで開発する](https://qiita.com/ravi_souza/items/b68bf37f76058f724405)

Serverless Frameworkとの違いは色々あるのですが、開発したAPIをローカルで実行する場合の最大の違いは……

1. リクエストをローカルで受け取る
2. **Dockerプロセスが立ち上がる**
3. Lambdaが実行される

という三段階にあると考えています。
特に2番が曲者で、上記の記事では

- DynamoDBをDockerでローカルに構築する
- DynamoDBが起動するネットワークを作成
- Lambda実行のDockerプロセスが機動するネットワークを指定

という流れで、LambdaがDynamoDBにアクセスできるようにしています。

……これ、**デバッグが難しいです**……
DynamoDBが動いているネットワークが指定されちゃってるので、逆にローカル実行した際にネックになっちゃってるみたいでアクセスが上手くできなかったです。

一応"Configure"から色々設定してデバッグの引数などは設定できるようですが、一方VSCodeでリモートデバッグ的な設定をして、Dockerプロセスの生成後にステップ実行……みたいな方法は厳しそうでした。
そこまでやるなら普通にServerless Frameworkで構築して、引数：eventのモックみたいなものを作成してそのままデバッグしてしまったほうが楽なのでは？

……という感が否めませんでした。
やってみると実際そっちのほうが楽でした。

それと、AWS Toolkitが出て間もないので情報がやや少ないというのも大きいです。
SAM自体はAWS Toolkit以前からあったのでそれなりに情報があるのですが、AWS Toolkitを使わない場合「Serverless Frameworkよりも多少複雑で、プラグインが少ない」フレームワークという印象で、正直あまり良い印象はありません。

# 結論
Serverless FrameworkとSAMの最大の差は、要するに
「プラグインの豊富さ」
だと考えています。
例えばSAMで例に出した記事の場合はDynamoDB localを自前で構築していますが、自前で構築する要素が多くなればなるほどそれは負債になる可能性が高いわけで……
これがプラグインひとつ定義すればOKということであれば非常に楽です。

そんなこんなで今回私が関わった案件ではServerless Frameworkを選定しましたが、今後SAM・AWS Toolkitのプラグインや知見が増えた場合、SAMのほうが楽に構築できるようになるかもしれません。

# その他フレームワークについて
Serverless Framework、SAMに限らずこの手のフレームワークにはPython系のフレーム枠であるZappaなども存在しています。
……が。**情報が明らかに少ないです。**
システム立ち上げにおいて「みんな使ってるのを使う」はある程度の正義です。

また、Lambdaを用いたAPI構築の場合、真打ちの真打ちと言ってもいいでしょう、**[AWS Cloud9](https://aws.amazon.com/jp/cloud9/)**が存在しています。
こちらはフレームワークではなくIDEです。
そのままの状態でデバッグしたり、そのままデプロイしたり、かなり機能が豊富で
「アレ？ これがベストなのでは？」
と思い、色々検証しましたが……

1. ステップ実行がうまく動いてくれない
2. 何故かデバッグ時の「停止」ボタンがない

ことで心が折れました。
1に関しては自分の設定ミスの可能性もありますので、もう少し調査したら変わっていたかもしれません。

が、2に関してはもう完全に心が折れました。
「そこ！？」と言われてしまうかもしれませんが、**「当然のように大抵のIDEで備えているものがパッと分かる位置に置いていない」IDEの使用を今後の参画者に強いる**のは、自分には無理だなぁと。
これはいくらなんでも学習コストや開発者に対する制約が多すぎるなという感想です。

# 結論の結論
Serverless Frameworkはとてもいいぞ。
SAMとAWS Toolkitは今後に期待ですね。