Rust + Rocket + Diesel 构建 REST API 全程指南
作者:API传播员 · 2025-11-03 · 阅读时间:8分钟
本文详细介绍了如何使用Rust的Rocket框架和Diesel ORM创建REST API。Rust以其内存安全性和高效性著称,通过所有权机制避免内存泄漏。Rocket简化了Web应用开发,而Diesel提供了与关系型数据库的交互能力。文章包含从项目初始化、数据库迁移到API实现的完整步骤,适合希望利用Rust构建高性能Web服务的开发者。
文章目录
一、Rust 优势速览
- 性能:接近 C 的执行速度,零成本抽象
- 内存安全:所有权模型编译期杜绝空指针/悬垂指针
- 无 GC:适合后端、嵌入式、CLI 等多场景
- 工具链:Cargo 一键管理依赖、构建、测试、文档
💡 AI 助攻
想自动生成带注释的Cargo.toml?用「代码生成」提示词,30 秒即可拿到模板,再交给「代码优化」砍掉冗余特性,编译速度提升 20%!
二、技术栈选型
| 组件 | 用途 | 版本 |
|---|---|---|
| Rocket | Web 框架 | 0.4.x |
| Diesel | ORM & 查询构建器 | 1.4.x |
| PostgreSQL | 关系型数据库 | 14+ |
| Serde | JSON 序列化 | 1.0 |
| BCrypt | 密码哈希 | 0.10 |
三、项目初始化与结构
cargo new hello-rocket-bin --bin
cd hello-rocket-bin
Cargo.toml 关键依赖:
[dependencies]
rocket = "0.4.11"
rocket_contrib = "0.4.11"
diesel = { version = "1.4.8", features = ["postgres"] }
dotenv = "0.15.0"
serde = { version = "1.0", features = ["derive"] }
bcrypt = "0.10.0"
项目骨架:
src/
├── main.rs # Rocket 路由与启动
├── lib.rs # 模块汇总
├── schema.rs # Diesel 自动生成
├── models.rs # 实体与 JSON 映射
├── routes/ # 业务路由
└── db.rs # 数据库连接池
四、数据库迁移(PostgreSQL)
1. 安装 Diesel CLI
cargo install diesel_cli --no-default-features --features postgres
2. 配置环境变量
echo "DATABASE_URL=postgres://user:password@localhost/db_name" > .env
diesel setup
3. 创建迁移
diesel migration generate create_roles
diesel migration generate create_users
up.sql 示例:
CREATE TABLE roles (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL
);
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
role_id INTEGER REFERENCES roles(id)
);
down.sql:
DROP TABLE users;
DROP TABLE roles;
应用迁移:
diesel migration run
# 自动生成 src/schema.rs
🔍 AI 审查
把「Diesel 迁移脚本」提交评审?「代码审查助手」可自动检查 SQL 注入、字段冗余,提前发现 80% 潜在 Bug!
五、定义模型与模式
// src/models.rs
use serde::{Deserialize, Serialize};
use crate::schema::{roles, users};
#[derive(Queryable, Serialize)]
pub struct Role {
pub id: i32,
pub name: String,
}
#[derive(Insertable, Deserialize)]
#[table_name = "roles"]
pub struct NewRole {
pub name: String,
}
#[derive(Queryable, Serialize)]
pub struct User {
pub id: i32,
pub name: String,
pub role_id: i32,
}
#[derive(Insertable, Deserialize)]
#[table_name = "users"]
pub struct NewUser {
pub name: String,
pub role_id: i32,
}
六、数据库连接池
// src/db.rs
use rocket::request::Request;
use rocket::response::Response;
use rocket::fairing::{Fairing, Info, Kind};
use diesel::pg::PgConnection;
use diesel::prelude::*;
use r2d2_diesel::ConnectionManager;
use r2d2::{Pool, PooledConnection};
type PgPool = Pool<ConnectionManager<PgConnection>>;
pub struct DbConn(pub PooledConnection<ConnectionManager<PgConnection>>);
impl<'a, 'r> FromRequest<'a, 'r> for DbConn {
type Error = ();
fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
let pool = request.guard::<State<PgPool>>()?;
match pool.get() {
Ok(conn) => Outcome::Success(DbConn(conn)),
Err(_) => Outcome::Failure((Status::ServiceUnavailable, ())),
}
}
}
七、CRUD 路由实现
1. 新增角色
#[post("/roles", format = "json", data = "<new_role>")]
fn create_role(new_role: Json<NewRole>, conn: DbConn) -> Json<Value> {
let role = conn.run(|c| {
diesel::insert_into(roles::table)
.values(&new_role.into_inner())
.get_result::<Role>(c)
.expect("Error saving role")
});
json!({ "id": role.id, "name": role.name })
}
2. 新增用户
#[post("/users", format = "json", data = "<new_user>")]
fn create_user(new_user: Json<NewUser>, conn: DbConn) -> Json<Value> {
let user = conn.run(|c| {
diesel::insert_into(users::table)
.values(&new_user.into_inner())
.get_result::<User>(c)
.expect("Error saving user")
});
json!({ "id": user.id, "name": user.name, "role_id": user.role_id })
}
3. 查询所有用户
#[get("/users")]
fn get_users(conn: DbConn) -> Json<Value> {
let users = conn.run(|c| {
users::table
.inner_join(roles::table)
.load::<(User, Role)>(c)
.expect("Error loading users")
});
json!(users)
}
4. 更新用户信息
#[put("/users/<id>", format = "json", data = "<user>")]
fn update_user(id: i32, user: Json<NewUser>, conn: DbConn) -> Json<Value> {
conn.run(|c| {
diesel::update(users::table.find(id)))
.set(&user.into_inner())
.execute(c)
.expect("Error updating user");
});
json!({ "status": "success", "id": id })
}
5. 删除用户
#[delete("/users/<id>")]
fn delete_user(id: i32, conn: DbConn) -> Json<Value> {
conn.run(|c| {
diesel::delete(users::table.find(id)))
.execute(c)
.expect("Error deleting user");
});
json!({ "status": "success", "id": id })
}
八、启动与测试
1. 启动服务
cargo run
# 默认监听 localhost:8000
2. 快速验证(curl)
# 新增角色
curl -X POST localhost:8000/roles \
-H "Content-Type: application/json" \
-d '{"name":"admin"}'
# 新增用户
curl -X POST localhost:8000/users \
-H "Content-Type: application/json" \
-d '{"name":"Alice","role_id":1}'
# 查询用户列表
curl localhost:8000/users
# 更新用户
curl -X PUT localhost:8000/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"Alice Smith","role_id":1}'
# 删除用户
curl -X DELETE localhost:8000/users/1
✅ AI 补救
把「curl 测试命令」写进 README 太麻烦?用「代码文档生成器」提示词,自动在函数头部生成标准注释,提醒后续接入 Postman 集合,文档一键达标!
九、进阶路线图
| 阶段 | 技术点 | 工具/库 |
|---|---|---|
| ① 认证 | JWT + Rocket 中间件 | rocket-jwt |
| ② 分页 | limit/offset 查询 |
diesel-pagination |
| ③ 日志 | 结构化日志 | tracing |
| ④ 容器化 | 多阶段构建 | Docker |
| ⑤ CI/CD | GitHub Actions | cargo test + clippy |
十、总结与下一步
通过本教程,您已学会:
- 使用 Rocket 定义 REST 端点
- 使用 Diesel 进行类型安全的 CRUD
- PostgreSQL 迁移与连接池管理
- JSON 自动序列化/反序列化
下一步可在此基础上添加认证、分页、OpenAPI 文档等功能,打造生产级后端。祝编码愉快!
今晚就 push 到 GitHub,明天就能用 Fly.io 一键部署!🚀
热门推荐
一个账号试用1000+ API
助力AI无缝链接物理世界 · 无需多次注册
3000+提示词助力AI大模型
和专业工程师共享工作效率翻倍的秘密
热门API
- 1. AI文本生成
- 2. AI图片生成_文生图
- 3. AI图片生成_图生图
- 4. AI图像编辑
- 5. AI视频生成_文生视频
- 6. AI视频生成_图生视频
- 7. AI语音合成_文生语音
- 8. AI文本生成(中国)
最新文章
- API协议设计的10种技术
- ComfyUI API是什么:深入探索ComfyUI的API接口与应用
- 从架构设计侧剖析: MCP vs A2A 是朋友还是对手?
- Kimi Chat API入门指南:从注册到实现智能对话
- 免费查询公司注册信息API的使用指南
- 防御 API 攻击:保护您的 API 和数据的策略
- 香港支付宝实名认证:是什么?怎么用?
- 如何获取 Coze开放平台 API 密钥(分步指南)
- 如何保护您的API免受自动化机器人和攻击 | Zuplo博客
- ASP.NET Core Minimal APIs 入门指南 – JetBrains 博客
- 什么是 OpenReview
- Vue中使用echarts@4.x中国地图及AMap相关API的使用