Rust + MongoDB + Actix Web:构建 CRUD REST API 教程
作者:API传播员 · 2025-09-17 · 阅读时间:6分钟
文章目录
在本教程中,我们将使用 Rust、MongoDB 和 Actix Web 创建一个支持 创建、读取、更新和删除(CRUD) 操作的 REST API。以 Person 和 Hobby 两个模型为例,这两个模型存在一对多关系:在 MongoDB 中,Hobby 集合通过引用 Person 的 ID 来实现关联。
最终,我们将实现如下 REST API 端点:
POST /api/v1/persons:创建新 PersonGET /api/v1/persons:获取所有 PersonGET /api/v1/persons/:id:根据 ID 获取指定 PersonPUT /api/v1/persons/:id:更新指定 PersonDELETE /api/v1/persons/:id:删除指定 PersonPOST /api/v1/hobbies:创建新 HobbyGET /api/v1/hobbies:获取所有 HobbyGET /api/v1/hobbies/:id:根据 ID 获取指定 HobbyPUT /api/v1/hobbies/:id:更新指定 HobbyDELETE /api/v1/hobbies/:id:删除指定 Hobby
一. 准备工作
在开始之前,请确保已安装:
- Rust 和 Cargo CLI
- MongoDB
- Visual Studio Code (VSCode)(推荐)
二. 设置 MongoDB
1. 安装 MongoDB(macOS 示例)
brew tap mongodb/brew
brew install mongodb-community
brew services start mongodb/brew/mongodb-community
brew services list
2. 创建数据库用户
use admin
db.createUser({
user: "rustadmin",
pwd: "Adm1n_pwd",
roles: ["readWrite", "dbAdmin"]
})
3. 启用安全认证
编辑 MongoDB 配置文件:
security:
authorization: "enabled"
保存后重启服务:
brew services restart mongodb/brew/mongodb-community
三. 设置 Rust 开发环境
1. 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustc -V
cargo -V
2. 配置 VSCode
安装扩展:
- Rust
- Rust Analyzer
- Prettier – Code formatter
四. 创建 Rust REST-API 项目
1. 初始化项目
cargo new rust_mongo_rest
cd rust_mongo_rest
项目结构:
rust_mongo_rest/
├── Cargo.toml
└── src/
└── main.rs
2. 添加依赖项
在 Cargo.toml 中添加:
[dependencies]
actix-web = "4"
mongodb = "3.1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
dotenv = "0.15"
futures = "0.3"
tokio = { version = "1", features = ["full"] }
chrono = { version = "*", features = ["serde"] }
运行:
cargo build
五. 连接 MongoDB
1. 创建 .env
DB_USERNAME=rustadmin
DB_PASSWORD=Adm1n_pwd
DB_URL=mongodb://localhost:27017
DB_NAME=rust_mongo
DB_AUTH_SOURCE=admin
2. 实现数据库连接 (src/db.rs)
use mongodb::{options::{ClientOptions, Credential}, Client};
use std::env;
pub async fn get_mongo_client() -> Client {
dotenv::dotenv().ok();
let username = env::var("DB_USERNAME").expect("DB_USERNAME must be set");
let password = env::var("DB_PASSWORD").expect("DB_PASSWORD must be set");
let host = env::var("DB_URL").unwrap_or_else(|_| "localhost".to_string());
let auth_source = env::var("DB_AUTH_SOURCE").unwrap_or_else(|_| "admin".to_string());
let credential = Credential::builder()
.username(Some(username))
.password(Some(password))
.source(Some(auth_source))
.build();
let client_options = ClientOptions::builder()
.hosts(vec![host])
.credential(Some(credential))
.build();
Client::with_options(client_options).unwrap()
}
六. 创建模型
1. 文件结构
mkdir src/models
touch src/models/person.rs
touch src/models/hobby.rs
touch src/models/mod.rs
2. 定义模型
person.rs:
use mongodb::bson::oid::ObjectId;
use serde::{Deserialize, Serialize};
use chrono::Utc;
#[derive(Debug, Serialize, Deserialize)]
pub struct Person {
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
pub id: Option<ObjectId>,
pub name: String,
pub email: String,
pub created_at: chrono::DateTime<Utc>,
}
hobby.rs:
use mongodb::bson::oid::ObjectId;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct Hobby {
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
pub id: Option<ObjectId>,
pub hobby_name: String,
pub description: String,
pub person: Option<ObjectId>,
}
mod.rs:
pub mod person;
pub mod hobby;
七. 创建处理器和路由
1. 处理器文件夹
mkdir src/handlers
touch src/handlers/person.rs
touch src/handlers/hobby.rs
touch src/handlers/mod.rs
在 person.rs 和 hobby.rs 中实现 CRUD 逻辑。
2. 路由配置 (src/routes.rs)
use actix_web::web;
use crate::handlers::{person, hobby};
pub fn configure_routes(cfg: &mut web::ServiceConfig) {
cfg.service(
web::scope("/api/v1")
.route("/persons", web::post().to(person::create_person))
.route("/persons", web::get().to(person::get_persons))
.route("/persons/{id}", web::get().to(person::get_person_by_id))
.route("/persons/{id}", web::put().to(person::update_person_by_id))
.route("/persons/{id}", web::delete().to(person::delete_person_by_id))
.route("/hobbies", web::post().to(hobby::create_hobby))
.route("/hobbies", web::get().to(hobby::get_hobbies))
.route("/hobbies/{id}", web::get().to(hobby::get_hobby_by_id))
.route("/hobbies/{id}", web::put().to(hobby::update_hobby_by_id))
.route("/hobbies/{id}", web::delete().to(hobby::delete_hobby_by_id)),
);
}
八. 启动应用程序 (main.rs)
use actix_web::{App, HttpServer};
use crate::db::get_mongo_client;
mod db;
mod models;
mod handlers;
mod routes;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let client = get_mongo_client().await;
HttpServer::new(move || {
App::new()
.app_data(client.clone())
.configure(routes::configure_routes)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
九. 测试 REST API
启动应用:
cargo run
示例:创建 Person
curl -X POST http://127.0.0.1:8080/api/v1/persons \
-H "Content-Type: application/json" \
-d '{"name": "Graydon Hoare", "email": "graydon@example.com"}'
通过本教程,你已成功使用 Rust、MongoDB 和 Actix Web 构建了一个完整的 CRUD REST API,支持一对多模型关联,可作为后续业务扩展的基础。
热门推荐
一个账号试用1000+ API
助力AI无缝链接物理世界 · 无需多次注册
3000+提示词助力AI大模型
和专业工程师共享工作效率翻倍的秘密
最新文章
- 将 GraphQL 单体迁移至 Apollo Federation
- 声音即身份:声纹识别API如何改变身份验证的未来
- 国内API KEY 密钥免费的AI平台及其使用指南
- 全面解读:REST API与OpenAPI的区别、应用及最佳实践指南
- 5款强大且高效的API漏洞扫描工具推荐
- Twitter (x) API 介绍:在线使用和集成指南
- DeepSeek+ima:打造高效个人知识库,提升学习与工作效率
- API设计模式:粒度细化 vs 粒度粗化的利弊分析
- 解读 TaskMatrix.AI
- API协议设计的10种技术
- ComfyUI API是什么:深入探索ComfyUI的API接口与应用
- 从架构设计侧剖析: MCP vs A2A 是朋友还是对手?