examples/ssr-routing
概要
fandhe-frontend フレームワークの SSR(サーバーサイドレンダリング)+ ルーティングの正本サンプルです(イシュー #499)。templates/(fw new が 展開する「生成の雛形」)とは異なり、本サンプルは crates.io へ公開済みの fandhe-frontend-core / fandhe-frontend-app / fandhe-frontend-server (いずれも v0.2.0、イシュー #1159 で追随)をバージョン依存として実際に使う「正本」であり、 examples/ 配下に追加される以降の全サンプルが従う標準構成(examples 規約) の初例です。
学べること
fandhe_frontend_app::Loadertrait の自作実装(fandhe_frontend_app::DemoItemsLoader/DemoItemDetailLoaderへの決め打ちを避けた最小サンプル)fandhe_frontend_server::ssr::respond_withによる一覧・詳細画面の SSR 応答組み立てfandhe_frontend_app::router::Routerを独自ルート(/hello/:name)に直接使う実演と、Params(URL デコードされていない生文字列)を必ずtext()経由で出力する既定 エスケープの実践- 既定エスケープ(REQ-1): HTML はすべてノード木 API(
el/p/text/page_shell)で組み立て、format!によるタグ文字列の直接組み立て・raw_html()は使いません fandhe_frontend_core::el_owned/attr_if/attr_if_value(イシュー #1121)による条件付き属性の組み立て。elのVec<(&str, &str)>がformat!/to_stringした動的な属性値と相性が悪い制約をel_ownedのVec<(String, String)>で外し、attr_if/attr_if_valueが返すOption<(String, String)>をchain/flattenで合成して条件付き属性 (/hello/:nameの名前が既定値かどうかで排他出力するdata-default-greeting/data-greeting-for)を実演します
前提
- Rust ツールチェーン(
cargo) - crates.io(
https://index.crates.io/https://static.crates.io)への到達性 (依存解決に使用します) fw gate --project examples/ssr-routingを実行する場合は clippy component / cargo-deny が必要です(tools/ci/ensure-gate-tools.shで導入できます)
動かし方
# 詳細画面(200)
cargo run -- /items/1
# 未知パス(404)
cargo run -- /unknown
# 一覧画面(既定 "/")
cargo run
# Router 実演(/hello/:name、text() 経由で name を出力)
cargo run -- /hello/world
# テスト(既定エスケープ回帰を含む)
cargo test
# fw gate(リポジトリルートから実行)
tools/ci/ensure-gate-tools.sh
cargo run -p fandhe-frontend-cli -- gate --project examples/ssr-routing主要ファイル
| ファイル | 説明 |
|---|---|
Cargo.toml | crates.io バージョン依存 3 件のみ(fandhe-frontend-core / -app / -server)。root workspace から独立した [workspace] members = ["."] |
structure.toml | fw gate が唯一の情報源として読む構造マニフェスト |
clippy.toml | raw_html() 迂回検出ポリシー(templates/default/ と内容同一) |
deny.toml | 依存ポリシー(templates/default/ と内容同一) |
src/main.rs | SSR CLI エントリ(Loader 2 種 + respond_with + Router 実演) |
tests/routing.rs | respond_with の 200/404・既定エスケープ回帰テスト |