
2026/07/18 5:41
トップコート:Rust をフルスタックで開発するための完全なフレームワーク
RSS: https://news.ycombinator.com/rss
要約▶
日本語翻訳:
Topcoat は、シンプルさと生産性を重視したモジュール型でバッテリー込みの Rust フルスタックフレームワークです。現在初期実験段階にあり、Node.js や複雑なビルドステップを必要としません。資産バンドリングにはコンパイルされた Rust バイナリを使用し、進化に伴う不具合(breaking changes)が発生する可能性があります。
その核心的な革新は、サーバーサイドレンダリングであり、Rust サーバー側で型チェック済みの
$(...) 式を瞬時にブラウザ側の JavaScript に変換することで、 별도의 API レイヤを不要にします。このアプローチは、シグナルによる効率的なインタラクティビティ、非同期コンポーネント内での直接データベース照会、#[shard] マークで特定された更新を実現し、レイテンシーを引き起こす往復通信を排除します。フレームワークは view! マクロによる強力な HTML テンプレート、Rust の制御フローに馴染みのある機能、Web フォント、アイコン(Iconify を含む)、Fontsource、および部分的な HTML スワップのための htmx などのユーティリティをサポートしています。
主な特徴には、ディレクトリ構造からルートツリーを推論するオプションの自動ルーティング、機能フラグで有効化する組み込み Tailwind CSS サポート、ファイルを積極的にキャッシュする資産パイプラインが含まれます。
Cx コンテキスト、メモ化 (#[memoize])、暗号化されたセッション/クッキー、そして複雑なミドルウェアではなく単なる関数としてモデル化した認証などのリクエスト処理機能により、样板を削減します。含まれる #[component], attributes!, class! などのマクロもまた、コンポーネントの作成とスタイリングをさらに簡素化します。本文
Topcoat: Rust 向けフルスタックフレームワーク
Topcoat は、モジュール化され機能完備の Rust フレームワーク です。シンプルさと生産性を最優先しており、フルスタックアプリケーション開発に最適です。
注意: 本プロジェクトは初期段階であり実験的であるため、破壊的な変更が発生する可能性があります。 新しいプロジェクトのセットアップについては「Getting started」ガイドをご参照ください。
基本構造とサンプルコード
Rust を使用してサーバーサイドでレンダリングし、クライアント側でもインタラクティブな挙動を実現するサンプルです。
use topcoat::{ Result, router::{Router, RouterBuilderDiscoverExt, page}, view::{component, view}, }; #[tokio::main] async fn main() { // ルートを自動的に発見してビルド topcoat::start(Router::builder().discover().build()).await.unwrap(); } // ルート "/" のページ定義 #[page("/")] async fn home() -> Result { view! { <!DOCTYPE html> <html> <body> // コンポーネントの呼び出し hello(name: "World") </body> </html> } } // サーバーサイドでレンダリングされ、JS にも翻訳されるコンポーネント #[component] async fn hello(name: &str) -> Result { view! { <h1>"Hello, " (name) "!"</h1> } }
Topcoat の特徴
🚀 余計なコードなしでクライアント側リアクティビティを実現
Topcoat はすべてのマークアップをサーバーサイドでレンダリングします。これにより、以下の利点があります。
- 非同期処理と DB アクセス: コンポーネント内で直接データベースに問い合わせたり、非同期処理を行えます。
- ボイラープレートの排除: 従来の API レイヤーを作るために必要な余分な記述が不要です。
- サーバーへの往復通信の回避:
表現は型チェックされた Rust コードで、Topcoat はこれをサーバーサイドで評価し、同時に JavaScript に翻訳してブラウザ側で即時再実行します。$(...) - ビルドステップの簡素化: Wasm バンドルやクライアント側のビルドステップが不要です。
view! { // 初期状態:false signal open = false; // ブラウザ内で完結;サーバーとの往复通信は発生しない。 <button @click=$(|_e| open.set(!open.get()))>"What is Topcoat?"</button> // クリックした時のみ表示(クライアントサイドでトグル) <p :hidden=$(!open.get())>"A fullstack Rust framework."</p> }
シャード(Shard)によるサーバー側更新が必要な場合
最新の検索結果のように、サーバー側の更新が必須な場合は、コンポーネントを
アトリビュートでマークします。#[shard]
- 変更を検知するとサーバー側で再レンダリングを実行し、新しい HTML をそのまま置換します。
引数の値が変化した際に自動的にトリガーされます。$(...)
#[component] async fn search() -> Result { view! { signal query = String::new(); // ユーザー入力を検知し、シグナルを更新 <input @input=$(|e: Event| query.set(e.target.value))> // 入力値の変化に応じてサーバー側で再レンダリング search_results(query: $(query.get())) } } // サーバーサイドロジックを持つシャードコンポーネント #[shard] async fn search_results(cx: &Cx, query: String) -> Result { view! { <ul> // データベース問い合わせなど、ご自身で実装するサーバーサイドロジック: for product in search_products(cx, &query).await? { <li>(product.name)</li> } </ul> } }
🎨 強力で見慣れた HTML テンプレート
view! マクロは、HTML と Rust の両方の精神を尊重しています。テンプレート内に Rust の制御構造を自由に使用できます。
- ループ処理 (
)for - 条件分岐 (
)if - 動的な属性やテキストの埋め込み
view! { <nav> // アイテムリストのループ for item in nav_items { <a href=(item.url) // 現在のパスの場合のみクラスを付与 if item.url == current_path { aria-current="page" class="active" } > (item.label) </a> } </nav> }
コード整形(Formatting)
プロジェクト全体でマクロの形式を整えるには、
**topcoat fmt** CLI コマンドを使用します。
🗂️ モジュールベースのルーティング
ビルドステップを伴わずに、アプリのモジュール構造からルートツリーを自動的に推測するオプションを提供します。
src/ |-- app.rs -> / (ルート用の <html> レイアウトもここ) `-- app/ |-- about.rs -> /about |-- _marketing.rs (レイアウト、URL セグメントなし) |-- _marketing/ `-- pricing.rs -> /pricing |-- posts.rs -> /posts |-- posts/ `-- id.rs -> /posts/{post_id} `-- api/ `-- health.rs -> GET /api/health
📦 資産バンドリング(Asset Bundling)
バンドラーはコンパイルされたバイナリ内の
呼び出しをスキャンし、すべてのファイルをローカルの資産ディレクトリにコピー(またはダウンロード)します。これにより、攻撃的なブラウザキャッシュ戦略を用いて効率的に配信できます。asset!
const FERRIS: Asset = asset!("./ferris.png"); view! { <img src=(FERRIS)> }
- Web フォント:
(Google Fonts) との統合をサポート。Fontsource - アイコン:
アイコンセットとの簡単な統合をサポート。Iconify
🎨 Tailwind CSS のネイティブサポート
プロジェクトに Tailwind CSS を統合するには、
フィーチャーを有効にします。Node.js の依存関係が不要です。tailwind
view! { // スタイルシートを自動バンドルして読み込む <link rel="stylesheet" href=(topcoat::tailwind::stylesheet!())> }
Topcoat を学び始める:学習リソースと機能一覧
まずは以下のステップから始めましょう。
- [Getting started]: 新しいプロジェクト作成、CLI インストール、開発サーバー実行。
- ソースコードの形式化:
でマクロを含む形式を整える。topcoat fmt
主要な機能カテゴリ
🛠️ レンダリング系
マクロ: テンプレート構文、制御構造、条件付き属性などの定義。view!
マクロ: 子コンテンツを持つ非同期関数をコンポーネントとして定義。#[component]
マクロ: 再利用可能なランタイム属性断片の作成。attributes!
マクロ: 静的・条件的なエントリからスペース区切りのクラスリストを生成。class!
🚦 ルーティング系
- Router: ページ、レイアウト、API ルート(手動定義と自動検出)。
- モジュールベースのルーティング: モジュールツリーからルートテーブルを自動的に導出。
🔗 リクエストとの連携
- リクエストコンテキスト (
): ページ、レイアウト、コンポーネントが読み取る値へのアクセス。Cx - アプリコンテキスト: タイプにキー付けし、長期間存続する値をリクエスト間で共有。
- メモ化(Memoization):
を用いてリクエスト単位のキャッシュとファノートデデュプリケーションを実現。#[memoize] - 関数・ミドルウェアではないモデル: 認証などのリクエストスコープの懸念事象をモデル化する推奨手法。
- クッキー: サイン付け、暗号化、プレフィックス付きを含むクッキー・ジャルの読み書き。
- セッション: ブラウザ由来ストレージを用いたセッション認証(ライフサイクル、スライド式有効期限、トークンローテーション)。
📂 資産システム
- Assets: Rust で資産を宣言し、コンテンツハッシュ付き URL で配信。
- Fonts: Web フォントをバンドリングして配信。
- Icons: Iconify アイコンセットのダウンロードまたは独自の宣言。
⚡ クライアント側リアクティビティ
- ランタイム: シグナル、
表現、$(...)
イベントハンドラ、@
属性。:bind - Expressions: Rust/JavaScript の双方向表达式言語とその語彙。
- Procedures: ブラウザから呼び出せる非同期サーバー関数。
- Shards: 引数が変更された際にサーバー側で再レンダリングされるコンポーネント。
🔌 サードパーティ統合
- Tailwind: Node を使わず、資産パイプラインに組み込まれた Tailwind CSS。
- htmx: リクエスト/レスポンスヘッダーヘルパーを用いて、サーバー側から部分的な HTML スワップを駆動。