Topcoat:Rust 全栈框架
本文目录
Rust 的全栈框架
Topcoat 是一个模块化、开箱即用的 Rust 框架,用于构建全栈应用。它优先考虑简单性和生产力。参见 Learn Topcoat 开始使用,或查看 Roadmap 了解接下来会有什么。
早期阶段且处于实验状态。预计会有破坏性变更。
use topcoat::{
Result,
context::Cx,
router::{module_router, page},
view::{View, component, view},
};
#[tokio::main]
async fn main() {
topcoat::start(module_router!().build()).await.unwrap();
}
#[page]
async fn home(cx: &Cx) -> Result<impl View> {
Ok(view! {
<!DOCTYPE html>
<html>
<body>
hello(name: "World")
</body>
</html>
})
}
#[component]
async fn hello(cx: &Cx, name: &str) -> Result<impl View> {
Ok(view! { <h1>"Hello, " (name) "!"</h1> })
}
Topcoat 的不同之处#
无需样板代码的客户端响应性#
Topcoat 在服务器上渲染所有标记:组件可以是异步的,并直接查询数据库,从而消除了独立 API 层所需的全部传统样板代码。但交互性不必付出一次往返的代价。$(...) 表达式是普通的类型检查 Rust 代码,Topcoat 会在服务器上为初始渲染求值,也会把它翻译成 JavaScript,使其在浏览器中即时重新运行。不需要 wasm 包,也不需要客户端构建步骤:
#[component]
async fn faq(cx: &Cx) -> Result<impl View> {
let open = signal(cx, || false);
Ok(view! {
// 完全在浏览器中运行;没有服务器往返。
<button @click=$(|_e| open.set(!open.get()))>"What is Topcoat?"</button>
<p :hidden=$(!open.get())>"A full-stack Rust framework."</p>
})
}
当更新确实需要服务器时,例如获取新的搜索结果,把组件标记为 #[shard]。每当其某个 $(...) 参数发生变化,Topcoat 就会在服务器上重新渲染它,并把新 HTML 原地替换:
#[component]
async fn search(cx: &Cx) -> Result<impl View> {
let query = signal(cx, String::new);
Ok(view! {
<input @input=$(|e: Event| query.set(e.target.value))>
// 随着用户输入而更新。
search_results(query: $(query.get()))
})
}
#[shard]
async fn search_results(cx: &Cx, query: String) -> Result<impl View> {
Ok(view! {
<ul>
// 你自己的服务器端代码,比如数据库查询:
for product in search_products(cx, &query).await? {
<li>(product.name)</li>
}
</ul>
})
}
强大且符合直觉的 HTML 模板#
view! 宏忠于 HTML 和 Rust。在模板中使用熟悉的 Rust 控制流:
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>
}
使用 topcoat fmt CLI 命令自动格式化代码库中的 view! 片段(及其他宏)。
基于模块的路由#
Topcoat 可选地从应用的模块结构推断路由树(无需构建步骤):
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
可编辑的预制组件#
Topcoat UI 是一个基于 Tailwind 的组件库,灵感来自 shadcn/ui。组件通过 topcoat ui CLI 命令复制到你的项目中,这意味着你可以自由更改其设计和功能以适应你的用例:
#[component]
async fn delete_card(cx: &Cx) -> Result<impl View> {
Ok(view! {
card(
card_header(
card_title("Delete workspace")
card_description(
"This permanently removes the workspace and all of its data."
)
)
card_footer(
attrs: attributes! { class="justify-end" },
button(variant: ButtonVariant::Ghost, "Cancel")
button(variant: ButtonVariant::Destructive, "Delete workspace")
)
)
})
}
资源打包#
打包器会扫描编译后的二进制文件中的 asset! 调用,把每个文件复制(甚至下载)到本地资源目录,并让 Topcoat 以激进的浏览器缓存高效地提供这些资源。
const FERRIS: Asset = asset!("./ferris.png");
view! { <img src=(FERRIS)> }
Topcoat 还附带 Web 字体和图标工具,以及 Fontsource(Google Fonts)和 Iconify 的便捷集成。
内置 Tailwind 支持#
启用 tailwind 特性,把 Tailwind 集成到项目中:
view! { <link rel="stylesheet" href=(topcoat::tailwind::stylesheet!())> }
学习 Topcoat#
从这里开始#
- 入门:使用
topcoat new创建应用并运行开发服务器。 - 手动设置:自行添加依赖并连接一个最小应用。
- 源代码格式化:对宏体使用
topcoat fmt。
渲染#
view!混合 HTML、Rust 表达式、控制流和组件调用。#[component]使异步函数可以带具名参数和子内容从标记中调用。attributes!收集属性,以传递给组件并展开到元素上。class!合并基础、可选和条件 CSS 类。suspense在内容加载时显示回退内容。error_boundary在渲染失败时显示回退。live!和emit!在异步工作产生新 HTML 时替换页面的一部分。
路由#
- Router:页面、布局和 API 路由;支持手动和自动发现。
- 基于模块的路由:从模块树派生路由表。
- 链接到处理器:使用
href!生成导航链接、表单操作和重定向。
处理请求#
- 上下文(
Cx):读取请求数据和按类型存储的值。使用路由构建器的.with添加共享值,或使用cx.with为请求的一部分添加值。 - 记忆化:使用
#[memoize]进行每请求缓存和扇出去重。 - Cookie:读写请求 cookie jar,支持签名、加密和带前缀的 cookie。
- 会话:自带存储的会话认证:登录/登出生命周期、滑动过期和 token 轮换。
资源系统#
- 资源:在 Rust 中声明资源,以内容哈希 URL 提供。
- 字体:打包并提供 Web 字体。
- 图标:下载 Iconify 图标集或声明自己的图标。
客户端响应性#
- 运行时:信号、
$(...)表达式、@事件处理器和:绑定属性。 - 表达式:双 Rust/JavaScript 表达式语言及其词汇表。
- 过程(Procedures):可从浏览器调用的异步服务器函数。
- 分片(Shards):参数变化时在服务器上重新渲染的组件。
- 客户端导航:链接、预取以及无需整页重新加载的导航。
其他#
- Topcoat UI:预制组件被复制到你的项目中供你编辑。
- 元数据:为搜索引擎和社交网络设置每个布局和页面的标题、描述和链接预览。
- 本地化:为每个请求选择语言,并显示 Fluent 文件中的翻译。
- 邮件:使用
Mail::builder构建邮件,通过 SMTP、文件或内存传输发送。 - OpenAPI:在声明 API 路由的地方描述它们,并从路由器生成 OpenAPI 文档。
第三方集成#
- Tailwind:无需 Node 的 Tailwind CSS,接入资源管道。
- htmx:使用请求/响应头助手从服务器驱动部分 HTML 替换。
- Alpine AJAX:使用 Alpine AJAX 的请求头约定从服务器驱动部分 HTML 替换。
- Datastar:通过服务器发送事件把元素和信号补丁到页面中。
路线图#
我们希望为 Topcoat 带来的计划功能。有想法?打开 issue。
- 静态导出
- (更多)响应性(
topcoat-runtime) - 更多 Topcoat UI 组件,完整“blocks”,例如登录表单
- 更好的 Toasty 集成(从表单安全创建/更新记录,而无需列出所有字段)
- 验证
- 部署 Topcoat 的文档
- 静态页面预渲染
- WebTransport
- 图像优化 / 缩放
- Markdown 支持
- 更易用的中间件,例如限流
- 认证
- 后台任务
- Islands
关于#
一个开箱即用、用于构建 Web 应用的框架。
MIT 许可证。