Loco 入门:Rust 版的 Rails
使用受Rails启发的Rust框架Loco构建Web应用。本文介绍安装CLI、生成CRUD API脚手架,并在Loco 1.2中添加后台任务处理器。
Loco 是一个受 Rails 启发的 Rust Web 框架。它将 Axum 路由、Sea-ORM 模型与迁移、后台 Worker 以及代码生成器统一集成在一条 cargo loco 命令之下。
如果你曾经在编写任何业务逻辑之前,花上整个周末把 Axum、ORM、迁移工具和任务队列拼接到一起,那么 Loco 正是为了替你省去这些工作而设计的。本指南将带你安装 Loco、创建一个 API 应用、通过脚手架生成资源,并添加一个后台任务。由于许多旧教程针对的是 1.0 之前的版本,下文所有命令均使用 Loco 1.2.0 中的 1.x CLI。如果你刚接触这门语言,建议先阅读 Rust 基础。
核心要点
- Loco 是一个仿照 Ruby on Rails 设计的 Rust Web 框架,基于 Axum 实现路由,基于 Sea-ORM 2.0 实现模型与迁移。
- 使用
cargo install loco安装 CLI。仅当应用需要使用数据库时,才需要额外执行cargo install sea-orm-cli。 - 在 Loco 1.2 中,
cargo loco generate scaffold会生成迁移、模型、实体、DTO 和 CRUD 控制器,并自动执行迁移,无需单独的迁移步骤。 - 新建 Loco 应用的开发服务器默认监听 5150 端口。
- 开发阶段,后台任务以
BackgroundAsync模式在进程内运行。生产环境中,通常会将其迁移到 Redis、Postgres 或 SQLite 队列,并由cargo loco start --worker进行处理。
Rust 中的 Loco 是什么?
Loco 是一个约定式(opinionated)的全栈 Rust 框架。原生 Axum 项目需要你自行做出的技术栈选型,Loco 都已替你完成。Loco 官网 列出其 HTTP 层采用 Axum,ORM 采用 Sea-ORM 2.0,同时内置了 Worker、调度器、邮件发送、存储和缓存等功能。你只需面对一套项目结构、一套配置系统和一个 CLI,而不必自己挑选五个 crate 再编写胶水代码把它们串起来。源代码托管在 GitHub 上。Loco 于 2026 年 7 月发布了首个稳定版本 1.0。
Loco 借鉴了哪些 Rails 理念?
Loco 沿用了 Rails 的四个惯例:每个项目都有统一且可预期的目录结构;由生成器编写样板代码;通过版本化迁移管理 Schema 变更;耗时任务交给后台作业处理。如果你熟悉 Django 或 Laravel,应该对这些理念并不陌生,只是叫法不同。
| 概念 | 含义 | Loco 1.2 命令或位置 |
|---|---|---|
| 约定优于配置 | 文件放在框架预期的位置 | src/ 和 config/ 下生成的目录结构 |
| 生成器 | 由 CLI 编写样板代码 | cargo loco generate scaffold、model、controller、worker |
| 迁移 | 版本化的 Schema 变更 | migration/src/,在执行 generate 时自动应用 |
| 后台任务 | 在请求周期之外执行的工作 | cargo loco generate worker、perform_later |
如何安装 Loco 并创建应用?
安装 Loco 只需两条 cargo 命令,创建应用再加一条即可。正如 Loco README 所述,只有当应用使用数据库时才需要安装 sea-orm-cli。本例使用 SQLite,因此需要安装:
cargo install loco
cargo install sea-orm-cli
接下来生成应用。如果同时传入全部四个参数,向导会跳过交互式提示,因此该命令可以写进脚本,并且每次都能得到相同的结果:
loco new --name tour_app --db sqlite --bg async --assets none
cd tour_app
cargo loco start
根据官方第一个应用教程,--db sqlite 选择 SQLite 作为数据库,--bg async 让后台任务在进程内运行,--assets none 则跳过视图脚手架,使应用只提供 JSON 接口。启动输出的最后一行表明服务器已就绪:
listening on port 5150
开发服务器默认监听 5150 端口。如配置参考文档所示,配置文件通过 get_env 调用读取 PORT 环境变量来设置端口,因此你可以在那里修改。由于选择了数据库,应用还自带了位于 /api/auth/* 下的内置认证路由。
旧教程中安装的是名为 loco-cli 的 crate。Loco 1.0 已移除该 crate,现在 CLI 以 loco 的名称安装。
如何用脚手架生成资源?
只需一条命令,Loco 脚手架即可生成一个可用的、基于数据库的 CRUD API:
cargo loco generate scaffold posts title:string! content:text --no-auth
在 Loco 1.2 中,cargo loco generate scaffold 会生成迁移、Sea-ORM 模型和实体、强类型的请求与响应 DTO,以及 CRUD 控制器。随后它会自动应用迁移并重新生成实体,因此你无需再单独运行迁移命令。
字段语法来自添加模型指南。以 ! 结尾的类型(如 title:string!)表示必填列;不带后缀的类型(如 content:text)表示可为空的列;^ 则将字段标记为唯一。脚手架生成的路由默认要求携带 JWT,匿名请求会返回 401。--no-auth 参数会将路由设为公开,以便让本演示保持简单。
本指南涉及的生成项目部分结构如下(仅展示部分内容):
tour_app/
├── config/development.yaml
├── migration/src/
└── src/
├── app.rs
├── controllers/posts.rs
├── dtos/
├── models/_entities/
└── workers/
要测试新接口,请重启服务器并发送一个 POST 请求:
curl -X POST -H "Content-Type: application/json" \
-d '{"title":"Tour post","content":"hi"}' localhost:5150/api/posts
返回的 JSON 以 {"id":1, 开头,随后回显已存储的文章内容。
如何在 Loco 中添加后台任务?
Loco 的后台任务是一个带有强类型参数结构体的 Worker 模块,通过 perform_later 将其加入队列。生成一个 Worker:
cargo loco generate worker notifier
added: "src/workers/notifier.rs"
injected: "src/workers/mod.rs"
injected: "src/app.rs"
正如后台 Worker 指南所解释的,生成器总是将结构体命名为 Worker,并将其放在独立的模块中,旁边还有一个空的 WorkerArgs 结构体供你填充。因此,生成的 notifier Worker 完整路径为 workers::notifier::Worker。在 src/workers/notifier.rs 中,为 WorkerArgs 添加一个字段,并替换 perform 的函数体。build 及生成文件中的其余部分保持不变:
#[derive(Deserialize, Debug, Serialize)]
pub struct WorkerArgs {
pub post_id: i64,
}
// inside the generated `impl BackgroundWorker<WorkerArgs> for Worker`
async fn perform(&self, args: WorkerArgs) -> Result<()> {
println!("new post created: {}", args.post_id);
Ok(())
}
然后打开 src/controllers/posts.rs,在脚手架生成的 create 处理函数中,紧接着插入新文章的那一行(let item = item.insert(&ctx.db).await?;)之后添加以下代码。自 Loco 1.0 起,生成的主键类型为 i64,因此 item.id 可以直接赋值给 post_id,无需类型转换:
crate::workers::notifier::Worker::perform_later(
&ctx,
crate::workers::notifier::WorkerArgs { post_id: item.id },
)
.await?;
根据 Loco 1.0 发布说明,自 Loco 1.0 起,perform_later() 会以 Result<String> 的形式返回任务 ID。如果之后需要追踪任务,可以将其记录到日志中。
config/development.yaml 中将 workers.mode 设置为 BackgroundAsync,即以进程内 Tokio 任务的形式运行作业。BackgroundAsync 模式完全不需要队列后端。在生产环境中,请将 workers.mode 切换为 BackgroundQueue,配置 Redis、Postgres 或 SQLite 队列,并通过 cargo loco start --worker 在独立进程中处理任务。Postgres 和 SQLite 队列使用默认的 worker feature 即可,而 Redis 队列需要启用 worker_redis;具体后端在配置中通过 queue.kind 指定。切换后端时,Worker 和控制器代码都无需修改。
Loco 适合哪些人?
Loco 能大幅加快 Rust 后端的搭建速度,但并不能消除编写 Rust 本身的成本:
- 编译时间。 每次改动都要经过
rustc编译,因此”修改—重载”的循环比 Ruby、Python 或 PHP 框架更慢。 - 生态系统。 与 Rails 或 Django 多年积累的生态相比,第三方集成、插件以及已有的问答资源要少得多。
- 学习曲线。 生成的代码仍然默认你熟悉所有权、异步和 trait,处理函数中出现的编译错误也需要你能够读懂。
Loco 非常适合已经掌握 Rust、希望获得 Rails 式开发效率的开发者,以及有意转向 Rust 的 Rails、Django 或 Laravel 开发者。但如果你要同时学习 Web 服务器和 Rust,那么把它作为第一个后端框架并不明智。如果你还在犹豫是否值得为 Web 开发学习 Rust,可以阅读 Web 开发者是否需要 Rust。
总结
Loco 为 Rust 开发者提供了 Rails 带给 Ruby 开发者的体验:一个 CLI、可预期的项目结构,以及内置的迁移和后台任务,这一切都构建在 Axum 和 Sea-ORM 之上。请使用本指南中的 1.x 命令,而不是旧教程里 1.0 之前的命令。下一步,你可以使用 cargo loco generate model 添加第二个资源,然后按照后台 Worker 指南,将队列从 BackgroundAsync 迁移到持久化后端。
常见问题
能否在 Loco 应用中使用现有的 Axum 中间件和提取器?
可以。Loco 在很大程度上是围绕 Axum 的胶水代码,因此实现了 FromRequestParts 的自定义提取器可以直接在 Loco 控制器中使用。如需挂载 Tower layer(例如 tower-http 的超时层或会话层),请在 src/app.rs 中实现 Hooks::after_routes,该方法会接收 Loco 已构建好的 Axum 路由器。
如何将 Loco 应用从 SQLite 切换到 Postgres?
在 config/development.yaml 或 config/production.yaml 中,将 database.uri 设置为 postgres:// 连接字符串。生成的配置会通过 get_env 读取 DATABASE_URL 变量的值,因此直接设置该环境变量同样有效。Loco 的默认配置期望用户名为 loco、密码为 loco,数据库名称由应用名和环境组成,例如 myapp_development。在 URI 中添加 sslmode=require 即可启用 Postgres TLS,无需额外的 Cargo feature。
如何将 Loco 应用部署到生产环境?
使用 cargo build --release 构建发布版二进制文件,然后将其连同 config/ 目录一起复制到服务器。目标机器无需安装 Rust 工具链或 cargo。在打包方面,cargo loco generate deployment 提供三种类型:docker、nginx 和 lambda。docker 会生成 Dockerfile 和 .dockerignore;nginx 会生成反向代理配置;lambda 会生成 AWS Lambda 入口并添加 lambda_http 依赖。生产环境配置位于 config/production.yaml。
Loco 的调度器与后台 Worker 有什么区别?
Worker 运行由代码通过 perform_later 加入队列的任务,而调度器则按时间表运行任务。调度器任务在配置 YAML 中声明,每个任务都可使用 cron 表达式或通俗英文描述的调度规则。run 的值指定一个已注册的 Loco task;当 shell 为 true 时,则指定一条 shell 命令。使用 --scheduler 参数可以让调度器与服务器一同运行,而无需启动 Worker 进程。
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k