使用 Rust 和 Actix Web 构建一个干净的 API

更新于 2026-01-17

Anthony Therrien 2024-09-17

引言

Rust 以其高性能、内存安全性和并发能力而闻名。在 Web 开发领域,Rust 可能不是你首先想到的语言,但它拥有一些强大的框架,可以帮助你构建高性能的 API。其中最受欢迎的框架之一就是 actix-web

在本文中,我们将引导你使用 Rust 和 actix-web 框架创建一个干净、健壮的 API。我们将涵盖从项目搭建、请求与响应处理、中间件添加,到保持清晰的项目结构等所有内容。

阅读完本文后,你将对如何使用 Rust 和 actix-web 构建一个结构良好、易于维护的 API 有全面的理解。

前提条件

在开始之前,请确保你已安装以下工具:

  • Rust(最新稳定版本):Rust 安装指南
  • Cargo(Rust 的包管理器)
  • 对 Rust 及其语法有基本了解

项目搭建

首先,我们创建一个新的 Rust 项目。打开终端并运行以下命令:

cargo new rust-api
cd rust-api

接下来,打开 Cargo.toml 文件,并添加我们需要的依赖项:

[dependencies]
actix-web = "4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
uuid = { version = "1", features = ["v4"] }
dotenv = "0.15"
tokio = { version = "1", features = ["full"] }

以下是每个依赖项的作用说明:

  • actix-web:我们将用于构建 API 的 Web 框架。
  • serdeserde_json:用于 JSON 数据的序列化和反序列化。
  • uuid:用于生成唯一标识符。
  • dotenv:用于管理环境变量。
  • tokio:异步运行时,帮助并发处理多个请求。

创建项目结构

为了保持项目的整洁和可维护性,我们采用一个结构化的目录布局。最终的项目结构如下所示:

rust-api/
│
├── src/
│   ├── handlers/
│   │   ├── mod.rs
│   │   ├── user_handler.rs
│   │
│   ├── models/
│   │   ├── mod.rs
│   │   ├── user.rs
│   │
│   ├── routes/
│   │   ├── mod.rs
│   │   ├── user_routes.rs
│   │
│   └── main.rs
│
└── .env

我们将分别为 handlers(处理器)、models(模型)和 routes(路由)创建目录,并在其中放置相应的模块。下面逐步实现。

1. 创建模型(Models)

首先创建 models 目录和 user.rs 文件:

mkdir src/models
touch src/models/user.rs

编辑 src/models/user.rs

use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Debug, Serialize, Deserialize)]
pub struct User {
    pub id: Uuid,
    pub username: String,
    pub email: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct CreateUser {
    pub username: String,
    pub email: String,
}
  • User:表示用户的主要数据结构。
  • CreateUser:用于创建新用户的简化结构。

接着创建 src/models/mod.rs 以导出模块:

pub mod user;

2. 创建处理器(Handlers)

处理器定义了 API 的业务逻辑。创建 handlers 目录和 user_handler.rs 文件:

mkdir src/handlers
touch src/handlers/user_handler.rs

编辑 src/handlers/user_handler.rs

use actix_web::{web, HttpResponse};
use uuid::Uuid;

use crate::models::user::{User, CreateUser};

pub async fn create_user(user: web::Json<CreateUser>) -> HttpResponse {
    let new_user = User {
        id: Uuid::new_v4(),
        username: user.username.clone(),
        email: user.email.clone(),
    };

    HttpResponse::Created().json(new_user)
}

pub async fn get_user(user_id: web::Path<Uuid>) -> HttpResponse {
    // 目前,我们仅返回一个模拟用户响应。
    let mock_user = User {
        id: *user_id,
        username: String::from("mock_user"),
        email: String::from("mock_user@example.com"),
    };

    HttpResponse::Ok().json(mock_user)
}

pub async fn health_check() -> HttpResponse {
    HttpResponse::Ok().json("API is up and running!")
}
  • create_user:处理创建新用户的请求。
  • get_user:根据用户 ID 获取用户数据(目前返回模拟数据)。
  • health_check:一个简单的健康检查路由,用于验证 API 是否正常运行。

创建 src/handlers/mod.rs 以导出模块:

pub mod user_handler;

3. 创建路由(Routes)

创建 routes 目录和 user_routes.rs 文件:

mkdir src/routes
touch src/routes/user_routes.rs

编辑 src/routes/user_routes.rs

use actix_web::web;

use crate::handlers::user_handler::{create_user, get_user, health_check};

pub fn init(cfg: &mut web::ServiceConfig) {
    cfg.service(
        web::scope("/api")
            .route("/users", web::post().to(create_user))
            .route("/users/{id}", web::get().to(get_user))
            .route("/health", web::get().to(health_check)),
    );
}
  • init:将路由注册到应用程序中。

创建 src/routes/mod.rs 以导出模块:

pub mod user_routes;

4. 设置主应用程序(Main Application)

现在,我们在 src/main.rs 中将所有部分整合起来:

mod handlers;
mod models;
mod routes;

use actix_web::{App, HttpServer};
use dotenv::dotenv;
use std::env;

use routes::user_routes::init;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    dotenv().ok();
    let host = env::var("HOST").unwrap_or_else(|_| "127.0.0.1".to_string());
    let port = env::var("PORT").unwrap_or_else(|_| "8080".to_string());

    println!("Server running at http://{}:{}", host, port);

    HttpServer::new(|| {
        App::new()
            .configure(init) // 初始化路由
    })
    .bind(format!("{}:{}", host, port))?
    .run()
    .await
}
  • 使用 dotenv 从环境变量中读取主机和端口信息。
  • 初始化在 user_routes 中定义的路由。

5. 添加环境变量

在项目根目录下创建 .env 文件,并添加以下内容:

HOST=127.0.0.1
PORT=8080

6. 测试 API

使用以下命令运行应用程序:

cargo run

你应该会看到如下输出:

Server running at http://127.0.0.1:8080

现在可以测试 API 端点:

健康检查(Health Check)

curl http://127.0.0.1:8080/api/health

预期输出

"API is up and running!"

创建用户(Create User)

curl -X POST -H "Content-Type: application/json" \
  -d '{"username":"john_doe", "email":"john@example.com"}' \
  http://127.0.0.1:8080/api/users

预期输出:包含用户信息的 JSON 响应(包括生成的 UUID)。

获取用户(Get User)

{user_id} 替换为上一步返回的用户 ID:

curl http://127.0.0.1:8080/api/users/{user_id}

预期输出:模拟的用户信息(当前实现中不依赖实际存储)。

结论

在本文中,我们详细介绍了如何使用 Rust 和 actix-web 构建一个干净、结构良好的 API。我们涵盖了以下内容:

  • 项目初始化和依赖配置;
  • 以模块化方式创建模型、处理器和路由;
  • 将路由集成到主应用程序中;
  • 使用环境变量提高配置灵活性。

通过这种方式组织你的 Rust Web 应用程序,你可以获得一个易于维护、可扩展的代码库,随着项目的发展也能轻松添加新功能。未来你可以进一步引入更复杂的业务逻辑、数据库集成以及中间件(如日志记录、认证、限流等)。

Rust 的性能优势和内存安全保障使其成为构建高可靠 API 的绝佳选择。

欢迎深入探索 actix-web 官方文档,了解更多高级特性,例如错误处理、应用状态管理、自定义中间件等。

祝你编码愉快!🎉