お疲れ様です、tomaです。
前回の記事で「RustでDjangoのようなフルスタック体験を」という旗揚げをしてから、少し時間が経ちました。
基盤を整えるフェーズから一歩踏み出し、現在は「いかに楽に、堅牢な管理画面を構築するか」という、フレームワークの真価を問うフェーズに突入しています。
今回のアップデートのテーマは、「ボイラープレートの殲滅とUXの血肉化」です。
泥臭いバグ修正から、Rustのメタプログラミングを駆使した効率化まで、現在のセーブポイントを詳細に記録しておきます。
前回のおさらい:何を目指していたか
このプロジェクト「rust_django」の目的は、Rustの速度を維持しつつ、Djangoのような「全部入り」の利便性を手に入れることです。
前回までは、RocketとSeaORMを組み合わせた基礎構造の設計を行っていました。
今回は、その上に乗る「管理画面(Admin UI)」を実用レベルに引き上げるための大規模な改修を行いました。
1. マクロの魔力:impl_admin_resource! の強化
Web開発で最も退屈で、かつ間違いが起きやすいのが「似たようなCRUD処理を何度も書くこと」です。
各モデル(User, Group, Todo…)ごとに一覧や作成のビューを手動で書いていては、いつまでも完成しません。
そこで、src/macros.rs に定義したマクロを大幅に拡張しました。
- デフォルトモード: 記述一行で、CRUDの全機能を自動生成。
- カスタムモード:
skip_create: trueのように指定することで、特定の処理だけを手動で実装可能に。
これにより、定型文的なコードを排除し、開発者は「そのモデル特有のロジック」だけに集中できるようになりました。
2. 実用性を求めて:ユーザー管理のリファクタリング
マクロは便利ですが、現実はそれほど単純ではありません。
例えば「ユーザー管理」では、パスワードのハッシュ化や多対多の権限グループ保存といった特殊な処理が必要です。
これまではロジックが混在していましたが、src/controllers/admin_users.rs として分離。
マクロの恩恵を受けつつ、保存ロジック(save メソッド)だけをオーバーライドする形に書き直しました。
「共通化できるところはマクロに任せ、特殊なところだけ手を入れる」。この柔軟性が、フレームワークとしての使い勝手を大きく左右します。
3. 「動けばいい」からの脱却:UXの細かなこだわり
今回の改修で、個人的に最も「やってよかった」と思っているのがエラーハンドリングの改善です。
以前はバリデーションエラー(入力ミスなど)が起きると、別のページにリダイレクトしていました。
しかし、これではユーザーがせっかく入力した内容が消えてしまい、非常にストレスフルです。
改善後:
エラー時はリダイレクトせず、ページを直接レンダリングするように変更しました。
入力内容をそのままフォームに保持しつつ、エラーメッセージを表示する。当たり前のような挙動ですが、この積み重ねが「ツール」としての完成度を高めてくれます。
4. 開発効率の秘密兵器:グローバルコンテキスト
Djangoには「Context Processor」という、どのテンプレートでも共通の変数を使える仕組みがあります。
これをRocketでも再現するために、AppTemplate と ContextFairing を導入しました。
ログイン中のユーザー情報やCSRFトークンを、各コントローラーで毎回取得して渡す必要はありません。
システム側で自動的にテンプレート変数に注入されるようになったことで、コードが劇的にスッキリしました。
トラブルシューティング:冒険に付き物の「落とし穴」
もちろん、順風満帆ではありませんでした。
ルーティングの設定ミスで `/admin/users/create` が 404 になり続けたり、グループ作成時にテンプレート名の不一致で 500 エラーを吐いたりと、細かなバグにも翻弄されました。
しかし、それらを一つずつ「なぜ起きたか」を分析し、マウントパスの修正やテンプレートパスの整合性を取ることで、より強固な構造へと昇華させることができました。
結び
今回のリファクタリングを通じて、単なる「動くコード」が「実用的なアプリケーション」へと成長し始めているのを感じています。
工数を削減しながら、ユーザー体験も向上させる。この両輪が揃ってこそ、フレームワークを作る意義があるのだと再確認しました。
次の目的地は、さらなる管理画面の機能拡張です。
また進捗があったら、ここで共有させていただきます。
それでは、次回のセーブレポートまで。
toma