Rust Loco Web框架
定位:Rust版 Rails,MVC全栈框架,底层基于 Axum + SeaORM,主打「约定优于配置」,面向独立开发者、SaaS项目,开箱即用大量企业功能。 仓库:https://github.com/loco‑rs/loco 版本:目前稳定版
loco‑rs 1.x,支持稳定 Rust。
Loco核心设计理念
- Rails式MVC架构:Model(模型)‑View(视图)‑Controller(控制器),固定目录结构,减少决策成本。
- 底层不造轮子:HTTP层用 Axum,ORM用 SeaORM,异步运行时Tokio,性能继承Axum的能力。
- Batteries‑included(内置全套):认证、后台任务、邮件、迁移、CLI脚手架、测试、配置、日志全部内置,不用到处找依赖。
- CLI脚手架工具:一键生成项目、模型、CRUD控制器、迁移文件,极大减少样板代码。
- 模块化:可以只使用部分组件,不需要全部功能。
Loco内置开箱即用功能
| 模块 | 说明 |
|---|---|
| HTTP路由 | 基于Axum,控制器组织路由,无大量魔法宏,普通async函数处理器 |
| 数据库ORM | SeaORM,支持PostgreSQL/SQLite,数据库迁移,模型关系、校验、事务 |
| 认证Auth | JWT、API Token、Session;自带注册/登录/找回密码;鉴权提取器Guard |
| 后台任务Worker | 内置任务队列;支持内存队列、Postgres队列、Redis分布式队列;异步耗时任务(发邮件、报表) |
| 邮件Mailer | 模板化邮件发送,支持本地调试与SMTP |
| 配置系统 | yaml配置文件,区分开发/测试/生产,支持环境变量覆盖 |
| 中间件 | 日志、trace id、CORS、请求限流,兼容Tower生态 |
| 模板渲染 | 支持tera模板引擎,服务端渲染HTML页面 |
| CLI工具 | loco new创建项目、generate scaffold生成CRUD、cargo loco dev热重载开发、cargo loco migrate数据库迁移、cargo loco routes查看全部接口 |
| 测试支持 | 内置测试工具,模型、控制器、任务都方便写单元/集成测试 |
Loco项目目录结构(CLI生成标准MVC)
myapp/
├── config/ # yaml配置:development.yaml / production.yaml
├── migration/ # SeaORM数据库迁移文件
├── src/
│ ├── controllers/ # 控制器,处理http请求
│ ├── models/ # SeaORM实体模型(数据库表)
│ ├── auth/ # JWT认证逻辑
│ ├── bgworker/ # 后台任务worker
│ ├── mailer/ # 邮件模板
│ ├── middleware/ # 自定义中间件
│ ├── views/ # 响应序列化视图、模板
│ └── main.rs
└── Cargo.tomlLoco快速上手
1. 安装loco CLI
bash
cargo install loco-cli2. 创建项目(选择 SaaS app,自带数据库+用户认证)
bash
loco new my_loco_app
cd my_loco_app3. 启动开发服务(热重载)
bash
cargo loco dev服务默认运行在 http://127.0.0.1:5150,已经自带 /api/auth/login、/api/auth/register 等认证接口。
4. 生成CRUD脚手架(一键生成模型+控制器+迁移)
bash
cargo loco generate scaffold post title:string content:text published:bool执行后自动生成:数据库迁移、model、controller、路由,完整RESTful CRUD接口。
Loco简单代码示例
控制器示例(src/controllers/posts.rs)
rust
use loco_rs::prelude::*;
use crate::models::_entities::posts;
// 列表接口
pub async fn list(State(ctx): State<AppContext>) -> Result<Response> {
let posts = posts::Model::find_all(&ctx.db).await?;
format::json(posts)
}
// 路由定义
pub fn routes() -> Routes {
Routes::new()
.prefix("posts")
.add("/", get(list))
}鉴权保护接口(使用Auth提取器)
rust
// 需要登录才能访问
pub async fn me(State(ctx): State<AppContext>, auth: Auth<User>) -> Result<Response> {
format::json(auth.user)
}路由挂载(src/controllers/app_routes.rs)
rust
pub fn routes() -> Routes {
Routes::new()
.prefix("api")
.add(posts::routes())
.add("/me", get(me))
}Loco vs Rocket vs Axum
| 框架 | 底层 | 定位 | 开发体验 | 适合场景 |
|---|---|---|---|---|
| Loco | Axum+SeaORM | Rails式MVC全栈框架 | 极高,CLI脚手架、内置认证/任务/邮件,约定优先 | SaaS、后台API、完整业务应用,单人快速开发 |
| Rocket | Tokio+自定义HTTP | 高层Web框架,宏驱动 | 好,内置json、数据库、guard;版本长期RC | 中小型API,追求简洁,不想用Axum底层写法 |
| Axum | Tokio+hyper | 底层HTTP工具库 | 中等,需要自己组装ORM、认证、任务,无约定 | 高性能微服务、自定义架构,追求极致可控 |
✅ 选型建议
- 想快速做完整业务后端,需要认证、后台任务、邮件,不想自己拼一堆库 → Loco
- 喜欢宏,追求简单的API服务,不需要复杂后台任务 → Rocket
- 追求极致性能、高度自定义,自己管理组件 → Axum
Loco优缺点
✅优点
- 开箱即用,生态完整:认证、后台任务、邮件、迁移全部内置,不用到处找库。
- CLI脚手架生产力极高,生成CRUD、模型,减少大量样板代码。
- 底层Axum+SeaORM,性能可靠,类型安全。
- MVC目录规范,团队协作友好。
- 支持生产部署,自带docker配置模板。
❌缺点
- 框架抽象层高,学习成本高于纯Axum,需要理解Loco的约定。
- 框架比较新,相比Rocket、Axum社区规模更小。
- 高度依赖框架约定,如果想要脱离框架做高度自定义,会比较别扭。
- 部分高级功能需要阅读源码,文档深度有限。
生产环境注意
- 配置文件
config/production.yaml,不要硬编码密钥、数据库密码,使用环境变量注入。 - 后台任务:生产建议使用
worker_redis分布式队列,不要用内存队列。 - 数据库迁移使用
cargo loco migrate执行。 - 可以直接编译二进制部署,也可以使用官方提供的Docker模板。
Loco.rs 完整REST API示例
基于
loco‑rs 1.x,底层 Axum + SeaORM,包含:JWT鉴权、CRUD、后台任务、CORS、配置 前置:已经安装loco-cli
1. 创建项目
bash
loco new loco-demo
# 选择:SaaS app(自带用户认证、数据库)
cd loco-demoCargo.toml 关键依赖(生成项目自带)
toml
[dependencies]
loco-rs = "1.0"
sea-orm = { version = "1.0", features = ["sqlx-postgres", "runtime-tokio-native-tls"] }
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }2. 配置文件 config/development.yaml
yaml
database:
uri: postgres://postgres:123456@localhost:5432/loco_demo
enable_migrations: true
auth:
jwt_secret: "dev_secret_key_123456"
jwt_expiry: 86400
cors:
enabled: true
allowed_origins: ["http://localhost:3000"]
worker:
mode: background生产环境
config/production.yaml密钥不要硬编码,使用环境变量覆盖。
3. 生成Post模型(脚手架一键CRUD)
bash
cargo loco generate scaffold post title:string content:text published:bool执行完自动生成:
- 数据库迁移文件
migration/xxx_create_posts.rs - Model实体
src/models/_entities/posts.rs - Controller控制器
src/controllers/posts.rs - 自动注册路由
执行数据库迁移
bash
cargo loco migrate4. 控制器代码 src/controllers/posts.rs
脚手架自动生成,我标注关键部分
rust
use loco_rs::prelude::*;
use crate::models::_entities::posts;
// 列表
pub async fn list(State(ctx): State<AppContext>) -> Result<Response> {
let items = posts::Model::find_all(&ctx.db).await?;
format::json(items)
}
// 获取单条
pub async fn get(Path(id): Path<i32>, State(ctx): State<AppContext>) -> Result<Response> {
let item = posts::Model::find_by_id(&ctx.db, id).await?;
format::json(item)
}
// 创建(需要登录鉴权)
pub async fn create(
State(ctx): State<AppContext>,
auth: Auth<models::users::Model>,
Json(params): Json<posts::CreateParams>,
) -> Result<Response> {
// auth.user 就是当前登录用户
let post = posts::Model::create(&ctx.db, params).await?;
format::json(post).status(Status::Created)
}
// 更新
pub async fn update(
Path(id): Path<i32>,
State(ctx): State<AppContext>,
Json(params): Json<posts::UpdateParams>,
) -> Result<Response> {
let post = posts::Model::update_by_id(&ctx.db, id, params).await?;
format::json(post)
}
// 删除
pub async fn delete(Path(id): Path<i32>, State(ctx): State<AppContext>) -> Result<Response> {
posts::Model::delete_by_id(&ctx.db, id).await?;
format::empty()
}
pub fn routes() -> Routes {
Routes::new()
.prefix("posts")
.add("/", get(list))
.add("/:id", get(get))
.add("/", post(create))
.add("/:id", put(update))
.add("/:id", delete(delete))
}路由注册 src/controllers/app_routes.rs
rust
use loco_rs::prelude::*;
pub fn routes() -> Routes {
Routes::new()
.prefix("api")
// 内置认证接口:/api/auth/register /api/auth/login /api/auth/me
.add(auth::routes())
// 我们的posts CRUD
.add(posts::routes())
}5. 后台任务 Worker示例
Loco内置任务队列,用于耗时操作(发邮件、生成报表) 新建
src/bgworker/send_notify.rs
rust
use loco_rs::prelude::*;
#[derive(Debug, Deserialize, Serialize)]
pub struct NotifyTask {
pub user_id: i32,
pub msg: String,
}
#[async_trait]
impl BackgroundWorker for NotifyTask {
type Input = NotifyTask;
type Output = Result<()>;
async fn perform(&self, _ctx: &AppContext, input: Self::Input) -> Self::Output {
println!("执行后台任务: user={}, msg={}", input.user_id, input.msg);
Ok(())
}
}在控制器调用后台任务
rust
// 在create接口里派发任务
NotifyTask::enqueue(&ctx, NotifyTask{
user_id: auth.user.id,
msg: "文章已创建".into()
}).await?;6. 启动服务
bash
cargo loco dev服务地址:http://127.0.0.1:5150
可用接口
| 接口 | 方法 | 说明 |
|---|---|---|
/api/auth/register | POST | 注册用户 |
/api/auth/login | POST | 登录获取JWT token |
/api/auth/me | GET | 获取当前登录用户(需要Bearer token) |
/api/posts | GET | 获取全部文章 |
/api/posts | POST | 创建文章(需要登录) |
/api/posts/:id | GET/PUT/DELETE | 单条CRUD |
请求鉴权:Header
Authorization: Bearer <token>
7. Rocket vs Loco 对比总结
| 维度 | Rocket 0.5‑rc | Loco.rs 1.x |
|---|---|---|
| 底层 | 自研HTTP,Tokio | Axum + SeaORM |
| 架构 | 宏驱动,无强制MVC | MVC约定,目录固定 |
| ORM | rocket_sync_db_pools(diesel) | SeaORM(现代ORM) |
| 认证 | 需要自己引入jwt库 | 内置JWT、Session |
| 后台任务 | 无内置,自己引入队列 | 内置Worker任务队列 |
| CLI脚手架 | 无官方CLI | 强大CLI:scaffold生成CRUD、迁移 |
| 邮件 | 需要第三方库 | 内置Mailer |
| CORS | rocket‑cors第三方 | 内置CORS配置 |
| 社区 | 成熟,资料多 | 较新,社区小 |
| 适合 | 小型API,喜欢宏写法 | 完整SaaS业务,快速搭建后端 |
选型建议
- 如果你想快速搭一套完整业务后端,有认证、后台任务、邮件、迁移,不想自己拼一堆库 → Loco
- 如果你喜欢简洁宏、做中小型API,不需要复杂后台任务 → Rocket
- 如果你想要极致灵活、自己组装全部组件 → Axum
生产注意事项
- JWT密钥、数据库密码不要硬编码,使用环境变量
- 生产环境worker不要使用内存队列,切换为redis队列
- 数据库迁移使用
cargo loco migrate - 项目自带Dockerfile,可以直接容器部署