🦀

Rust の Lambda 関数で DynamoDBにデータを書き込む api を作る

2023/07/21に公開

HTTP リクエストボディに記載した JSON の値を DynamoDB に保存する API を作成してみる。
基本的にはリファレンス通りにやる。
サンプルがあるのでこれを理解するつもりでやればOKだろう。

テンプレートの使用

色々めんどくさいので、SAM テンプレートから書き換えていく形にする
テンプレートを sam init で作る、前回作ったやりかたをそのまま利用。

ライブラリの追加

必要そうなライブラリを追加する。
AWS SDK for Rust の一覧から、aws-sdk-dynamodb があったのでこれを使う。

あとなんか aws-sdk-config は基本的にいるっぽい、これも入れておく

Config provides a way to keep track of the configurations of all the Amazon Web Services resources associated with your Amazon Web Services account.

また Hello World のサンプルでは lambda_runtime を使っていたが、サンプルコードでは lambda_http を使っていたのでこっちを使う。
使うために適宜コードは変更する。

Rust での HTTP イベントの処理

また、Lambda 用の Rust ランタイムクライアントでは、これらのイベントタイプを抽象化することもでき、どのサービスがイベントを送信するかに関係なく、ネイティブ HTTP タイプを使用できます。次のコードは前の例と同等で、Lambda 関数 URL、Application Load Balancer、API Gateway ですぐに使用できます。
らしい

受け取ったボディを json に変換するため serde_json を使う

cargo add aws-sdk-dynamodb aws-config lambda-http serde_json

コードの作成

DynamoDB に保存する Json 構造

何でもいいが、アカウント情報的な感じにした。
https://github.com/KIrie-0217/rust-dynamodb-sample/blob/fcf38a486263c69e0a293e70b457c56f1c0bc9d2/rust_app/src/main.rs#L7-L12

Lambda 初期化処理

初期化時にクライアントの構築を行う。リファレンス的にも初期化時に1度だけ行うのが良いらしい。

Note: Client construction is expensive due to connection thread pool initialization, and should be done once at application start-up.

クライアントは以下のコードで構築可能らしい。
https://github.com/KIrie-0217/rust-dynamodb-sample/blob/fcf38a486263c69e0a293e70b457c56f1c0bc9d2/rust_app/src/main.rs#L66-L67

Lambda イベントハンドラに対して作成したクライアントを渡す
やり方はデベロッパーガイドを参考にした

https://github.com/KIrie-0217/rust-dynamodb-sample/blob/fcf38a486263c69e0a293e70b457c56f1c0bc9d2/rust_app/src/main.rs#L69-L73

Dynamo DB にデータを追加する関数

Client 対して put_item() でアイテムを追加するリクエストを作成する。
各パラメータの型は AttributeValue で宣言する。
作成したリクエストは send() で実行できる。

https://github.com/KIrie-0217/rust-dynamodb-sample/blob/fcf38a486263c69e0a293e70b457c56f1c0bc9d2/rust_app/src/main.rs#L76-L100

Lambda イベントハンドラ

Client を受け取れるようにしたいので、引数に Client を追加する
https://github.com/KIrie-0217/rust-dynamodb-sample/blob/fcf38a486263c69e0a293e70b457c56f1c0bc9d2/rust_app/src/main.rs#L19-L22

Body を読み取って、json 形式で受け取る

https://github.com/KIrie-0217/rust-dynamodb-sample/blob/fcf38a486263c69e0a293e70b457c56f1c0bc9d2/rust_app/src/main.rs#L23-L38

テーブルにアイテムを追加する

https://github.com/KIrie-0217/rust-dynamodb-sample/blob/fcf38a486263c69e0a293e70b457c56f1c0bc9d2/rust_app/src/main.rs#L40-L41

Response 用の処理をする。
受け取った Json をそのまま返すことにする。

https://github.com/KIrie-0217/rust-dynamodb-sample/blob/fcf38a486263c69e0a293e70b457c56f1c0bc9d2/rust_app/src/main.rs#L43-L53

デプロイ

template.yaml で Method とか Path を適宜修正したらデプロイする
以下のコマンドでデプロイできる

sam build --beta-features
sam deploy --guided

IAM ロールを指定せずデプロイした場合、 DynamoDB への PutItem 権限が付与されていないので、付与する。

動作検証

作成された API エンドポイントに対して Json を投げてみる。

curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/addaccount -d '{"account_id": "1", "account_name": "from_curl","password": "aiueo"}'

>{"account_id":"1","account_name":"from_curl","password":"aiueo"}

DynamoDB にアイテムが追加されていることを確認する。

まとめ

  • サンプルをなぞるだけなので、特につまずくところはなかった
  • かんたんに色々できて助かる

Discussion