
現在、多くのエンジニアがRustに注目し始めており、Ruby on Railsなどのフレームワークでの開発経験を持つ人たちもRustの習得に取り組んでいます。Rustは所有権や借用といった独自の概念を持ち、習得には一定の学習コストが必要ですが、少しずつ理解を深めながら進めることが重要です。
特に、RustをWebアプリケーション開発に取り入れる際には、「Rustらしいコードとは何か」「効率的で拡張性のあるコードベースをどう作るか」といった課題が生じることがあります。このような課題に対処するため、Rustのベストプラクティスを学ぶ手段の一つとして「Awesome Rust」が有効です。このリポジトリには、多様な分野にわたるRustのプロジェクトが集約されており、Web開発における実践的な知見を得ることができます。
本記事では、「Awesome Rust」に掲載されているWebプログラミング関連プロジェクトを調査し、そこから得られた知見を紹介します。Rustを使ったWebアプリケーション開発を始める際の参考になれば幸いです。
1. revoltchat/backend
Revoltとは
Revoltはオープンソースのチャットプラットフォームで、ユーザーファーストな体験を重視して作られています。そのバックエンドはRustで書かれており、revoltchat/backendリポジトリでその実装を見ることができます。
このリポジトリにはスタイルガイドが存在し、プロジェクト全体でのコードの書き方や規約が説明されています。ここでは、Rustでwebバックエンドを書いていく上で参考になる部分を抜粋してみましょう。
ライセンス
Revoltのバックエンドは、 GNU Affero General Public License v3.0 (AGPL-3.0) の下でライセンスされています。
1.1 構造体のコメント
スタイルガイドには、「全ての構造体定義にはコメントを付けること」というルールがあります。
All struct definitions must be commented.

このように、構造体やそのフィールドに対して簡潔なコメントを付けることが推奨されています。
なぜコメントが重要なのか?
コードの可読性向上 フィールドの意味や役割が一目で分かるため、新しい開発者がコードを理解しやすくなります。特にnameやvalueなど、一般的な名称が使われる場合は、文脈がなければその意味を誤解する恐れがあります。
ドキュメント生成の自動化 Rustでは、///で始まるドキュメンテーションコメントを使用することで、自動的にrustdoc によるHTML形式のAPIドキュメントが生成できます。プロジェクトのドキュメントが整備されることで、チーム内外での情報共有がスムーズになります。
1.2 カスタムマクロで構造体の属性を簡潔に
Rustの特徴の一つに、#[derive(...)]アトリビュートを使ったトレイトの自動実装があります。ただし、これを構造体ごとに手動で記述すると、コードが冗長になる可能性があります。 Revoltのリポジトリでは、カスタムマクロを活用してこの問題を解決しています。
通常の記述例

カスタムマクロを利用した記述例

カスタムマクロの定義
以下のようなカスタムマクロが用意されています。

このようにマクロを使うことで、繰り返し作業を減らし、一貫性を保ちながらメンテナンス性の高いコードを書くことができます。
メリット
コードの簡潔さ手動での記述を減らし、見た目がすっきりします。
メンテナンス性の向上カスタムマクロを修正するだけで、すべての構造体に反映されるため、仕様変更にも柔軟に対応可能です。
1.3 シリアライズ条件を統一する
特殊な条件でシリアライズをスキップしたい場合、既存のヘルパー関数を活用することが推奨されています。
If special serialisation conditions are required, such as checking if a boolean is false, use the existing definitions for these functions from the crate root:

引用されたスタイルガイドでは、if_falseという関数を使用して、falseの場合にactiveフィールドをスキップする方法が推奨されています。
条件付きシリアライズをヘルパー関数にまとめることで、コードが簡潔になり、再利用性と一貫性が向上します。
公式ドキュメントも参考に
条件付きシリアライズについては、Serde公式ドキュメントにも詳しく説明されています。
他にもいろいろなものが用意されているので、確認してみるのも良いかもしれません。
例えば、Noneである場合、Optionをスキップする設定などは、よく使うかもしれないですね。

1.4 implブロックの整理とルール
Rustでは、構造体や列挙型に関連するメソッドや関数を定義するために、implブロックを使用します。Revoltのスタイルガイドには、implブロックの記述に関していくつかの指針が示されています。
implblocks may be defined below the struct definitions and should be ordered in the same order of definition. Methods in the block must follow the same guidelines as traits where-in: methods are ordered in terms of CRUD, there are empty line breaks, and methods are commented.
ガイドラインに基づくポイント
implブロックの位置implブロックは、対応する構造体や列挙型の直下に配置することで、コード全体の構造が分かりやすくなります。
メソッドの順序メソッドはCRUD(Create, Read, Update, Delete)の順序で記述することで、用途が整理され、他の開発者がコードを理解しやすくなります。
空行とコメントメソッド間に空行を挿入して視覚的な区切りを作り、各メソッドにコメントを付けることで、コードの意図を明確に伝えることができます。
整理されたimplブロックの例
以下に、ガイドラインに従ったimplブロックの例を示します。

メリット
可読性の向上順序や区切りが明確になることで、コードの全体像が把握しやすくなります。
メンテナンス性の向上一貫したスタイルで記述されているため、新しいメソッドを追加する際も迷いがありません。
このようなルールを守ることで、チームでの開発やコードの長期的な保守がスムーズになります。
また、これらのルールをlinterで設定できれば、自動的にコードスタイルをチェックできるので、レビューのコストも下げられて効率化できそうですね。
2. LemmyNet/lemmy
Lemmyとは
ここからは、Awesome Rustリポジトリに掲載されている別の例として、分散ソーシャルメディアプラットフォームであるLemmyのバックエンド実装を見てみましょう。
Lemmyは、Redditに似た機能を持つオープンソースの分散型ソーシャルニュースプラットフォームで、Rustで実装されています。
この章では、LemmyNet/lemmyの構成から、Rustで大規模なWebアプリケーションを設計・構築する際のポイントを見ていきたいと思います。
ライセンス情報
Lemmyは、GNU Affero General Public License v3.0 (AGPL-3.0) の下でライセンスされています。
2.1 モノレポ構成
以下は、Lemmyのリポジトリ構造の概要です。一部を抜粋してます。

Lemmyのリポジトリを覗くと、複数のRustクレートを1つのリポジトリに集約した「モノレポ」構成を取っていることが分かります。
src/ディレクトリにアプリケーション本体やルートエントリーポイントが置かれ、
crates/ディレクトリ配下にはapi/、api_common/、federate/、utils/といった、特定の機能や責任を担うクレートが整理されています。
このアプローチにより、プロジェクト全体の整合性を保ちながら、各コンポーネントを独立して開発・テストすることが可能です。
特徴と利点
依存関係管理の一元化:
すべてのクレートが同一リポジトリ内にあるため、互いの依存関係やバージョン調整が容易です。
コードの一貫性と再利用性向上:
共通機能はapi_common/やutils/といった専用クレートにまとめることで、重複を削減し、プロジェクト全体で統一的な実装を保つことが可能です。
モジュール間の明確な責務分割:
api/クレート: APIエンドポイント関連の実装
apub/、federate/クレート: Fediverse対応や外部連携機能
db_schema/、db_perf/、db_views/: データベーススキーマや最適化、ビュー機能の分離
機能ごとの独立開発・テスト:
各クレートは基本的に独立して開発・テストできるため、新機能追加やリファクタリングがプロジェクト全体に影響しにくいです。
このようなモノレポ構造は、大規模プロジェクトの効率的な管理に非常に適しています。
おわりに
今回はAwesome Rustの中からrevoltchat/backendとLemmyNet/lemmyを例に、RustでのWebバックエンド構築や大規模アプリケーション設計について紹介しました。
構造体のコメントやカスタムマクロを活用してコードの一貫性を保つこと
データのシリアライズルールを統一し、データ構造の設計意図を明確にすること
モノレポ構造やクレート間の依存関係を整理し、大規模プロジェクトを効率的に管理すること
これらの手法が、RustでWebアプリケーションを作る際のヒントになれば幸いです。これからもプロジェクトやOSSのコードを読みながら学びを深め、新たな知見を皆さんと共有していければと思います。