こんばんわ、hisayukiです。
先日やってみたこちらの話の続きです。
curlから動かせば、動作はするのですが・・・
実際、製造してるときにいちいちデプロイなんかやってられないですよね。
という仕組みもあるのですが、こちらはRust未対応。serverless-offline
なら、ローカルでLambda単体でテスト出来る仕組みはほしいですよね。
というわけで、いろいろ調べてみました
そもそも出来るのか?
結論から言えば出来ました!
ソースコード上げておきます。
というわけで、前回動かなかった問題点ローカル検証のやり方を書いていこうと思います!
まず何が問題だったのか?
先日の問題。
$ yarn sls invoke local -f rust-sample
<pre><code>省略</code></pre>
END RequestId: 6e3b851a-d6a7-1901-e5de-8d30cf4a4766
REPORT RequestId: 6e3b851a-d6a7-1901-e5de-8d30cf4a4766 Init Duration: 50.26 ms Duration: 8.23 ms Billed Duration: 100 ms Memory Size: 1536 MB Max Memory Used: 10 MB
{
"errorType": "Unhandled",
"errorMessage": "JsonError: invalid type: string \"\", expected struct LambdaRequest at line 1 column 2"
}
これは受け取り側のhandler
がRequest
を引数にしてるのに、何も送ってこないじゃんというお叱りでした。
ソースはこちらですね。
fn main() {
lambda!(handler)
}
fn handler(
_: Request,
_: Context,
) -> Result<impl IntoResponse, HandlerError> {
Ok(json!({
"message": "Go Serverless v1.0! Your function executed successfully!"
}))
}
動くように変更
というわけで、コマンド変更とRequestにちゃんと何かを送ってあげます。
結局一番時間がかかったのはこのRequestに何を渡せば動いてくれるかのところでした。
参考サイトはこちら。
まぁ、長いんだけど・・・
このjsonをexample_request.json
としてmain.rsと同じ階層にを作成
ディレクトリ構成はこんな感じです。
.
├── Cargo.lock
├── Cargo.toml
├── node_modules
├── package.json
├── serverless.yml
├── package.json
├── serverless.yml
├── src
│ ├── example_request.json
│ └── main.rs
└── yarn.lock
ローカル環境
まずはローカル環境で。
ここまで揃えてからsls invoke local
をやってみます。
$ yarn sls invoke local -f rust-sample --path src/example_request.json
yarn run v1.15.2
$ /Users/hisayuki/vscode/serverless-rust-sample/node_modules/.bin/sls invoke local -f rust-sample --path src/example_request.json
Serverless: Building native Rust rust-sample func...
Finished release [optimized] target(s) in 3.92s
adding: bootstrap (deflated 61%)
Serverless: Packaging service...
Serverless: Building Docker image...
START RequestId: 1e7fd52d-783b-189a-b5bd-2d76e6fce2c5 Version: $LATEST
{"statusCode":200,"headers":{"content-type":"application/json"},"multiValueHeaders":{"content-type":["application/json"]},"body":"{\"message\":\"Go Serverless v1.0! Your function executed successfully!\"}","isBase64Encoded":false}
END RequestId: 1e7fd52d-783b-189a-b5bd-2d76e6fce2c5
REPORT RequestId: 1e7fd52d-783b-189a-b5bd-2d76e6fce2c5 Init Duration: 35.61 ms Duration: 4.22 ms Billed Duration: 100 ms Memory Size: 1536 MB Max Memory Used: 10 MB
✨ Done in 31.04s.
morihisayuseinoMacBook-Pro:serverless-rust-sample hisayuki$
動いた!!!
動いたけど、用意したjsonが長すぎなので動く範囲で削ったjsonがこちら。
{
"path": "/",
"httpMethod": "GET",
"headers": {
"Host": "amazonaws.com"
},
"requestContext": {
"accountId": "",
"resourceId": "",
"stage": "dev",
"requestId": "",
"identity": {
"sourceIp": ""
},
"resourcePath": "",
"httpMethod": "",
"apiId": ""
},
"queryStringParameters": {}
}
こんだけでも全然動きます。
AWS上でLambda単体
今度はDeploy後の環境でやってみます。
$ yarn sls invoke -f rust-sample --path src/example_request.json
yarn run v1.15.2
$ /Users/hisayuki/vscode/serverless-rust-sample/node_modules/.bin/sls invoke -f rust-sample --path src/example_request.json
{
"statusCode": 200,
"headers": {
"content-type": "application/json"
},
"multiValueHeaders": {
"content-type": [
"application/json"
]
},
"body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\"}",
"isBase64Encoded": false
}
✨ Done in 3.42s.
AWS上でも動いた!
コンソール画面でも試してみます。
テスト用イベントにローカルで作ったexample_request.json
と同じイベントを作ります。
そして、そのままテスト実行
こちらも無事に動きました!!
AWS上でAPI Gateway
まずはテスト
“message”: “Internal server error”
おっと・・・・ここでまた動かない・・・・
ちなみにリソースのテストは動かないですが、ステージからURL叩いたら動きました。
これ突き詰めるかはちょっと後回し
正直、ここまで出来てたらAPI Gatewayのテスト流さなくてもローカルからcurl
叩いたほうが早い(;´∀`)
curl
こちらは前回に引き続き動いたので、問題なしです!
$ curl -X GET https://wwn47tcau9.execute-api.ap-northeast-1.amazonaws.com/dev/
{"message":"Go Serverless v1.0! Your function executed successfully!"}
まとめ
まだAPI Gatewayのテストが流れない問題はありますが、課題にしていた一々デプロイしないと検証できない件について解決。
これでhandlerの単体テストはRustのテスト機能で、Lambdaとしてはsls invoke local
でテストで、API Gatewayについてもdeploy後にcurlで試せるようになったので開発としては問題ないかなと。
あとは今回、lambda_http
のライブラリにあるRequest
を引数にしてたのでこうなりましたが、Requestじゃなくてもいいんじゃないか?
自作の引数でよいなら、ここまでやらなくてもよかったかも。
API Gatewayでテストが流れない件も含め、そのあたりはまた別の機会に調べてみます。
コメント