The Serverless Application Framework | Serverless.com
以前から気にはなっていたのですが、簡易的なAPIを作るために利用してみました。
同様のServerless Frameworkとしては、Ruby on Jets というのがあります。
こちらも触ってみたいところ。
ざっくり利用方法
Installation
sesrverless入れるだけです。
mkdir your_project
cd your_project
yarn init
yarn add serverless -D
Create your project
yarn run serverless create --template aws-ruby
Deploy
コマンド1発で、CloudFormation作ってくれて、s3、IAM、Lambda、ApiGateway、CloudWatchまで一気にやってくれます。
これはめちゃ便利で、驚きました。
yarn run serverless deploy -v
各種設定
Serverless Framework - AWS Lambda Guide - Serverless.yml Reference
ここに全部乗ってるので、詳細は公式Documentみるのが良いでしょう。
以下、今回利用した設定内容。baseはこれだけ。
provider
こんな感じ。
provider:
name: aws
runtime: ruby2.7
stage: dev
region: ap-northeast-1
apiGateway:
shouldStartNameWithService: true
shouldStartNameWithService は、正直どっちでも良いですが、次のmajor versionからAPI Gatewayのnaming-ruleが変更されるため、新しい方式に合わせるために入れてます。
Serverless Framework Deprecations
functions
こんな感じ。ポイントはcors: trueぐらいでしょうか。
functions:
exec:
handler: handler.exec
events:
- http:
path: html2haml
method: post
cors: true
注意事項
あとはhandler.rbにロジック書くだけで出来ちゃいますが、2つハマったところがあるので記載していきます。
Native Extension Gem
今回html2hamlを利用としたのですが、当然の如くnokogiri使ってまして、macでbuildしたgemをdeployしても動かないわけです。
そこで利用するのがlambci/lambda - Docker Hub。
buildの例にrubyがなかったり、ruby2.5の例のままですが、現在のlambda同様2.7が利用できます。
docker run -v `pwd`:/var/task -it lambci/lambda:build-ruby2.7 bundle install --path vendor/bundle --without development test
docker run --rm -v $PWD:/var/task:ro,delegated lambci/lambda:ruby2.7 handler.exec '{"body": "{\"html\":\"<span foo=\\\"foo\\\">test</span>\"}"}'
しかし、bundle installしたgemなどをzipに含めると転送量が多くなるという問題があり、これを解決するためにはlayerとして別管理するか、serverless-hooks-pluginを使ってdockerでinstallするという手法があるようです。(後者試してないのであとでやってみます。)
個人的にはどうも、この辺が面倒だと感じるので、serverlessバンザイ!という気持ちには今一つなれません。
ここに書いてるんですが、Responseの形式が決まっています。
API ゲートウェイでの「不正な Lambda プロキシ応答」または 502 エラーの解決
見落としてハマっていたのが、bodyの形式です。JSON.stringifyした文字列が必要でした。
rubyなので、hashをto_jsonすることで解消。
"body": JSON.stringify(responseBody),
ご参考
See Also
htmlをhamlに変換するサイトhtml2hamlを勢いで作った - rochefort's blog