百名山 API を開発しました | mountix APICLICK !

Rust | Web フレームワーク Axum で REST API を作る

Rust・AxumでREST APIを作る
  • URLをコピーしました!

Rust の Web フレームワーク Axum を使って REST API を作って render.com にデプロイしてみました。

目次

はじめに

Rust で Web アプリケーションを作成し render.com で公開してみたので、記事にまとめてみたいと思います。

Web フレームワークは Axum 、DBには MongoDB を採用しています。

Axum は公式の examples が充実していますが、検索してもなかなか実装例などをの情報がヒットしません。

また、 Rust と MongoDB の参考記事も少なく、苦労しました。

この記事や拙いソースコードが、少しでも誰かのお役に立てられれば幸いです!!!

作成したWebアプリケーション

mountix API

作成したのは、山の情報を取得できる REST API です。

APIのドキュメント も公開しているので、Postman や Insomnia 等のHTTPクライアントツールで遊んでいただけると嬉しいです!

Github

Githubでソースコードを公開しました。

将来、Rust で実務経験を積みたいエンジニアが開発を進めています笑

小出しに実装例を見るよりも伝わりやすい部分もあるかと思いますので、のっけておきます。

v1.1.0 時点のソースコードをもとに本記事を書いています。

エラーハンドリングまわりの実装が非常に雑です… もっと上手く実装できるはず。

今後、validator を使うようにリファクタ予定です。

技術スタック

Axum

tokio チーム製の Web サーバーを実装するためのクレートです。

actix-web を採用するか迷いましたが、今回は Axum を採用しました。

Axum の特徴を簡単に挙げておきます。

  • 非同期ランタイムに tokio が使われているため、tokio のバージョン管理から解放されること
  • マクロレスで実装されていること

MongoDB

データベースには MongoDB を採用し、ドライバーは MongoDB 公式の mongodb クレートを使用しました。

また、MongoDB を採用した理由は以下です。

  • Geospatial queries があり、地理空間検索が容易に実装できること
  • GET のエンドポイントのみを提供する REST API であり、特にデータの整合性に注意する必要もなくため、RDSであるメリットがないこと
  • tokio-runtimeを選択できること
  • MongoDB Atlas を利用すれば、低コストで運用できること

アーキテクチャ

レイヤードアーキテクチャ

レイヤードアーキテクチャでの実装については、以下の記事をとても参考にさせていただきました。

Axum での実装ポイント

Router と nest

Router を定義して、.nest() でネストさせることができます。

パスパラメータとクエリパラメータ

ハンドラの引数に PathQuery を渡すことで値を受け取ることができます。

serde の Deserialize が実装された構造体であれば、axum が裏で良しなに変換してくれます。

mongodb クレートを使う

ドキュメントの構造体を定義しておく

ドキュメントを表す構造体を定義し Deserialise を実装してcollectionで型指定しておけば、serde が良しなに変換してくれます。

検索時の Filter Document を動的に生成する

この実装例が見当たらず、苦労しました。

doc! マクロを使えば、Document そのものは簡単に生成できます。

クエリパラメータで受け取ったnameprefecturetagがあれば、条件に追加するといった処理になっています。

意図した動作はしていますが、もっとスマートに書けないものか模索中です…

Geospatial queries を使用する

$nearSphereは中心点の座標とそこからの距離(m)を引数で渡して、その範囲に存在するドキュメントを取得できます。

$nearnearSphereがありますが、距離の計算が平面か球体の違いがあります。

$boxは長方形の地理空間上に存在するドキュメントを取得できます。

[[左下隅の経度, 左下隅の緯度], [右上隅の経度, 右上隅の緯度]]の形式で指定します。

mongodb クレートの使い方も紹介しているので、良ければチェックしてください!

render.com にデプロイする

Heroku の無料プランが廃止されることとなりました。

無料枠狙いnの方々は、render.com に流れていくのではないでしょうか。

Rust で実装した Web アプリケーションを手軽に公開できる、良い選択肢だと思います。

ただ、やってみた系の記事もまだまだ少ないのが現状です。

Rust のデプロイ方法の参考記事を探すのにも苦労しました。

HOST と PORT を環境変数で管理できるように

render.com にデプロイする際、以下の制約があります。

  • HOST0.0.0.0
  • PORT は環境変数で受け取れるようにする

そのため、HOSTPORTどちらも環境変数で管理できるようにしておくと良いかと思います。

ローカルでのデバック時には 127.0.0.1:8080 で起動していますが、render.com の .env では HOST=0.0.0.0を定義し、PORT は未定義にしてあります。

HOST=127.0.0.1
PORT=8080
HOST=0.0.0.0

Health check 用のエンドポイントを実装しておく

今回、一番ハマったポイントかもしれません。

よく読めば、すんなり解決できたはずなのですが…笑

render.com で Rust の Web アプリケーションをデプロイする際、特に注意する点はありません。

以下のようにコマンド設定するだけで基本的にはOKなはずです。

  • Build Command: $ cargo build --release
  • Start Command: $ cargo run --release

ただし、私の場合は Health Check Pathを変更する必要がありました。(デフォルトは /

理由は、Health Check Path をネストさせており、ルート URL にアクセスすると404が返るためです。

Start Command 実行後にこの Health Check Path にリクエストが投げられ、200 OKのレスポンスが返るとデプロイ成功となるようです。

デプロイ時のログを見ていると、成功応答があるまで数分間、404 エラーが出続けていました笑

ちなみに、200 OKを返せと書いてありますが、204 No Contentでも問題ありませんでした。

おそらくですが、200番台の成功応答が返ればよいと思われます。(試してはないです)

render.com を使った感想

.env の管理が簡単

管理画面に Secret Files という設定項目があり、.env という名前でファイルを作成可能です。

もちろん、環境変数を個別に設定することも可能です。

.envで管理する環境変数が多い場合は非常に便利だなと感じました。

ファイル名は自由に設定できるので、.env 以外の設定ファイルをバージョン管理下に置かずに管理する場合も、活用できる機能だと思います。

カスタムドメイン設定が簡単

カスタムドメインについては、設定はとても簡単でした。

render.com で Web Service を公開すると、https://{your-app-name}.onrender.comというURLが発行されます。

お名前.com などの DNS レコード設定で、CNAME{your-app-name}.onrender.comで登録すればOKです。

デプロイ時間が長い

無料プランで稼働させているので、デプロイに10分弱かかります。

初回のデプロイはキャッシュが効かないので、もう少し時間がかかった記憶があります。

短くしたい場合は、有料プランを検討した方が良いかもしれません。

まとめ

エラーハンドリングやマイグレーション、テストコードなど課題がまだまだあるので、今後も開発を進めていきたいと思います。

本記事は Zenn.dev でも公開しています。

SQLx で PostgreSQL に接続する

データベースを MongoDB ではなく、PostgreSQL を使用した Todo アプリの Web アプリでも Axum を使用しました。

また、PostgreSQL のドライバーとして SQLx を使用しています。

ソースコードは、こちらも Github に置いてあります。

参考

Rust・AxumでREST APIを作る

この記事が気に入ったら
フォローしてね!

  • URLをコピーしました!

コメント

コメントする

目次