curlからもslsからでもLambda(Rust)を動かせるようにした

技術ネタ
この記事は約8分で読めます。

こんばんわ、hisayukiです。
先日やってみたこちらの話の続きです。

curlから動かせば、動作はするのですが・・・

実際、製造してるときにいちいちデプロイなんかやってられないですよね。

serverless-offlineという仕組みもあるのですが、こちらはRust未対応。
なら、ローカルでLambda単体でテスト出来る仕組みはほしいですよね。

というわけで、いろいろ調べてみました

スポンサーリンク

そもそも出来るのか?

結論から言えば出来ました!

ソースコード上げておきます。

GitHub - mori-hisayuki/serverless-rust-sample
Contribute to mori-hisayuki/serverless-rust-sample development by creating an account on GitHub.

というわけで、前回動かなかった問題点ローカル検証のやり方を書いていこうと思います!

まず何が問題だったのか?

先日の問題。

$ 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"
}

これは受け取り側のhandlerRequestを引数にしてるのに、何も送ってこないじゃんというお叱りでした。
ソースはこちらですね。

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に何を渡せば動いてくれるかのところでした。

参考サイトはこちら。

GitHub - softprops/lando: 📦 🚀 a smooth-talking smuggler of Rust HTTP functions into AWS lambda
📦 🚀 a smooth-talking smuggler of Rust HTTP functions into AWS lambda - softprops/lando

まぁ、長いんだけど・・・
この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でテストが流れない件も含め、そのあたりはまた別の機会に調べてみます。

コメント