Skip to content

Rust Loco Web框架 ​

定位:Rust版 Rails,MVC全栈框架,底层基于 Axum + SeaORM,主打「约定优于配置」,面向独立开发者、SaaS项目,开箱即用大量企业功能。 仓库:https://github.com/loco‑rs/loco 版本:目前稳定版 loco‑rs 1.x,支持稳定 Rust。

Loco核心设计理念 ​

  1. Rails式MVC架构:Model(模型)‑View(视图)‑Controller(控制器),固定目录结构,减少决策成本。
  2. 底层不造轮子:HTTP层用 Axum,ORM用 SeaORM,异步运行时Tokio,性能继承Axum的能力。
  3. Batteries‑included(内置全套):认证、后台任务、邮件、迁移、CLI脚手架、测试、配置、日志全部内置,不用到处找依赖。
  4. CLI脚手架工具:一键生成项目、模型、CRUD控制器、迁移文件,极大减少样板代码。
  5. 模块化:可以只使用部分组件,不需要全部功能。

Loco内置开箱即用功能 ​

模块说明
HTTP路由基于Axum,控制器组织路由,无大量魔法宏,普通async函数处理器
数据库ORMSeaORM,支持PostgreSQL/SQLite,数据库迁移,模型关系、校验、事务
认证AuthJWT、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.toml

Loco快速上手 ​

1. 安装loco CLI ​

bash
cargo install loco-cli

2. 创建项目(选择 SaaS app,自带数据库+用户认证) ​

bash
loco new my_loco_app
cd my_loco_app

3. 启动开发服务(热重载) ​

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 ​

框架底层定位开发体验适合场景
LocoAxum+SeaORMRails式MVC全栈框架极高,CLI脚手架、内置认证/任务/邮件,约定优先SaaS、后台API、完整业务应用,单人快速开发
RocketTokio+自定义HTTP高层Web框架,宏驱动好,内置json、数据库、guard;版本长期RC中小型API,追求简洁,不想用Axum底层写法
AxumTokio+hyper底层HTTP工具库中等,需要自己组装ORM、认证、任务,无约定高性能微服务、自定义架构,追求极致可控

✅ 选型建议

  • 想快速做完整业务后端,需要认证、后台任务、邮件,不想自己拼一堆库 → Loco
  • 喜欢宏,追求简单的API服务,不需要复杂后台任务 → Rocket
  • 追求极致性能、高度自定义,自己管理组件 → Axum

Loco优缺点 ​

✅优点 ​

  1. 开箱即用,生态完整:认证、后台任务、邮件、迁移全部内置,不用到处找库。
  2. CLI脚手架生产力极高,生成CRUD、模型,减少大量样板代码。
  3. 底层Axum+SeaORM,性能可靠,类型安全。
  4. MVC目录规范,团队协作友好。
  5. 支持生产部署,自带docker配置模板。

❌缺点 ​

  1. 框架抽象层高,学习成本高于纯Axum,需要理解Loco的约定。
  2. 框架比较新,相比Rocket、Axum社区规模更小。
  3. 高度依赖框架约定,如果想要脱离框架做高度自定义,会比较别扭。
  4. 部分高级功能需要阅读源码,文档深度有限。

生产环境注意 ​

  1. 配置文件 config/production.yaml,不要硬编码密钥、数据库密码,使用环境变量注入。
  2. 后台任务:生产建议使用worker_redis分布式队列,不要用内存队列。
  3. 数据库迁移使用 cargo loco migrate 执行。
  4. 可以直接编译二进制部署,也可以使用官方提供的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-demo

Cargo.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 migrate

4. 控制器代码 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/registerPOST注册用户
/api/auth/loginPOST登录获取JWT token
/api/auth/meGET获取当前登录用户(需要Bearer token)
/api/postsGET获取全部文章
/api/postsPOST创建文章(需要登录)
/api/posts/:idGET/PUT/DELETE单条CRUD

请求鉴权:Header Authorization: Bearer <token>

7. Rocket vs Loco 对比总结 ​

维度Rocket 0.5‑rcLoco.rs 1.x
底层自研HTTP,TokioAxum + SeaORM
架构宏驱动,无强制MVCMVC约定,目录固定
ORMrocket_sync_db_pools(diesel)SeaORM(现代ORM)
认证需要自己引入jwt库内置JWT、Session
后台任务无内置,自己引入队列内置Worker任务队列
CLI脚手架无官方CLI强大CLI:scaffold生成CRUD、迁移
邮件需要第三方库内置Mailer
CORSrocket‑cors第三方内置CORS配置
社区成熟,资料多较新,社区小
适合小型API,喜欢宏写法完整SaaS业务,快速搭建后端

选型建议 ​

  1. 如果你想快速搭一套完整业务后端,有认证、后台任务、邮件、迁移,不想自己拼一堆库 → Loco
  2. 如果你喜欢简洁宏、做中小型API,不需要复杂后台任务 → Rocket
  3. 如果你想要极致灵活、自己组装全部组件 → Axum

生产注意事项 ​

  1. JWT密钥、数据库密码不要硬编码,使用环境变量
  2. 生产环境worker不要使用内存队列,切换为redis队列
  3. 数据库迁移使用 cargo loco migrate
  4. 项目自带Dockerfile,可以直接容器部署