日本の山岳一覧・百名山 API を開発しましたCLICK !

Rust | Axum と MongoDB でつくる 日本の山岳一覧・百名山 API

Rust Advent Calendar 2022
  • URLをコピーしました!

この記事は Rust Advent Calendar 2022 の 20 日目の記事です!

目次

はじめに

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

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

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

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

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

Web アプリケーション

mountix API

山岳一覧・百名山の情報を取得できる REST API を開発、公開してみました。

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

GitHub

GitHub でソースコードも公開しました。

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

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

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

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

技術スタック

Axum

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

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

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

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

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 の無料プランが廃止されてしまったので、今回は 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分弱かかります。

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

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

まとめ

やはり、何かをつくって公開するのが一番勉強になる…

Rust を業務で使える機会を虎視眈々狙っているので、今後も Rust を触り倒したいと思います🫰🌟

P.S. お察しの通り、山を題材にしたのは 登山が趣味だからです⛰️🏔️

参考

Rust Advent Calendar 2022

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

  • URLをコピーしました!

コメント

コメントする

目次