Skip to content

alchemy-studio/rust-web-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 

Repository files navigation

rust-web-app

项目简介

这是一个基于Rust Axum框架的生产级Web应用程序示例,展示了如何使用Rust构建高性能、安全且可维护的Web服务。

Rust Axum 完整课程源代码

代码已更新至 AXUM 0.7 标签: axum-06-to-07

本仓库包含 Rust Axum 完整课程的源代码,课程可在 YouTube 上观看。代码采用 MIT 或 Apache 许可证,可免费使用。

完整的 Rust Web 应用生产蓝图课程和仓库位于 https://rust10x.com/web-app(YouTube 视频:第01集 - Rust Web 应用 - 从课程到生产编程

重要提示:请确保刷新此仓库。我为 AUTH_TOKENcookie.add 实现了一个修复(详见下方注释部分)。

这里有一个由 @FloWi 制作的按章节分叉版本。非常感谢!

技术栈

  • Web框架: Axum - 基于Tokio的高性能Web框架
  • 异步运行时: Tokio - Rust的异步运行时
  • 数据库: PostgreSQL - 强大的关系型数据库
  • 数据库访问: SQLx - 异步SQL工具库
  • 认证: 基于Cookie的自定义认证系统
  • 日志: tracing - 用于分布式追踪的日志库
  • 序列化/反序列化: serde - 高效的数据序列化框架

项目结构

src/
├── _dev_utils/       # 开发工具和辅助函数
├── model/            # 数据模型和业务逻辑
│   ├── error.rs      # 模型层错误处理
│   ├── store.rs      # 数据库连接管理
│   ├── task.rs       # 任务模型
│   └── ticket.rs     # 票据模型
├── web/              # Web层和HTTP处理
│   ├── mw_auth.rs    # 认证中间件
│   ├── routes_login.rs # 登录路由
│   ├── routes_static.rs # 静态文件路由
│   └── routes_tickets.rs # 票据API路由
├── config.rs         # 应用配置
├── ctx.rs            # 请求上下文
├── error.rs          # 应用错误处理
├── log.rs            # 日志功能
├── main.rs           # 应用入口点
├── model.rs          # 模型层入口
└── web.rs            # Web层入口

启动数据库

# 启动 postgresql 服务器 docker 镜像:
docker run --rm --name pg -p 5432:5432 \
   -e POSTGRES_PASSWORD=welcome \
   postgres:17

# (可选)在 pg 上启动 psql 终端。
# 在另一个终端(标签页)中运行 psql:
docker exec -it -u postgres pg psql

# (可选)让 pg 打印所有 sql 语句。
# 在上面启动的 psql 命令行中执行。
ALTER DATABASE postgres SET log_statement = 'all';

开发(REPL)

# 终端 1 - 运行服务器。
cargo watch -q -c -w src/ -x "run"

# 终端 2 - 运行测试。
cargo watch -q -c -w examples/ -x "run --example quick_dev"

运行应用

RUST_LOG=info cargo watch -q -c -w src/ -x "run"

运行测试

cargo watch -q -c -w examples/ -x "run --example quick_dev"

开发

# 终端 1 - 运行服务器。
cargo run

# 终端 2 - 运行测试。
cargo test quick_dev -- --nocapture

开发(监视模式)

注意:使用 cargo install cargo-watch 安装 cargo watch。

# 终端 1 - 运行服务器。
cargo watch -q -c -w crates/services/web-server/src/ -w crates/libs/ -w .cargo/ -x "run -p web-server"

# 终端 2 - 运行 quick_dev。
cargo watch -q -c -w crates/services/web-server/examples/ -x "run -p web-server --example quick_dev"

开发(替代方案)

# 终端 1 - 运行服务器。
cargo run -p web-server

# 终端 2 - 运行测试。
cargo run -p web-server --example quick_dev

单元测试(监视模式)

cargo watch -q -c -x "test -- --nocapture"

# 使用过滤器的特定测试。
cargo watch -q -c -x "test -p lib-core test_create -- --nocapture"

# 测试task.rs中所有测试函数
cargo watch -q -c -x "test model::task::tests -- --nocapture"

单元测试

cargo test -- --nocapture

cargo watch -q -c -x "test -p lib-core model::task::tests::test_create -- --nocapture"

API端点

端点 方法 描述 认证要求
/api/login POST 用户登录
/api/tickets GET 获取所有票据
/api/tickets POST 创建新票据
/api/tickets/:id DELETE 删除指定票据

架构设计

本项目采用分层架构设计:

  1. Web层:处理HTTP请求和响应,负责路由、中间件和请求/响应序列化

    • 认证(Authentication):验证用户身份
    • 请求解析:将HTTP请求转换为应用可处理的数据
    • 响应构建:将应用数据转换为HTTP响应
  2. 模型层:包含业务逻辑和数据访问

    • 授权(Authorization):检查用户权限
    • 业务规则:实现应用的核心功能
    • 数据访问:与数据库交互
  3. 上下文(Context):连接Web层和模型层

    • 用户身份:保存已认证用户的信息
    • 请求范围:在请求生命周期内共享数据

这种设计允许模型层独立于Web框架运行,便于在不同类型的服务中重用业务逻辑。

特定测试

# 测试 : async fn test_create_ok() -> Result<()> 
cargo watch -q -c -x "test test_create_ok -- --nocapture"

工具

cargo run -p gen-key

注释

  • 重要 - 对于 AUTH_TOKEN cookie,请确保调用 cookie.set_path("/");。参见提交 - 修复 AUTH_TOKEN cookie 问题
  • tests/quick_dev.rs 文件已移动到 examples/quick_dev.rs(代码相同),因为这样更合适,并且似乎解决了在 Windows 上同时运行 testrun 的限制。
  • 在我的 Fedora Linux 环境中,对于 cargo watch(最新版本 8.4.0)需要使用 --poll 标志 - 服务器和测试都需要。 没有它就不会更新。参见 #1
  • 确保使用 axum 版本 0.6.16 或更高版本,因为版本 0.6.15 在静态路由方面有一个错误。
  • 这里有一个由 @FloWi 制作的按章节分叉版本。非常感谢!

此仓库可在 GitHub 上找到。

应用程序架构与流程

程序启动运行流程

flowchart TD
    A[程序入口 main.rs] --> B[初始化日志 tracing_subscriber]
    B --> C[初始化开发环境 _dev_utils::init_dev]
    C --> D[创建 ModelManager]
    D --> E[加载配置 config.rs]
    E --> F[创建数据库连接池 model/store.rs]
    F --> G[定义API路由 routes_tickets.rs]
    G --> H[定义公共路由 routes_hello.rs]
    H --> I[合并API和公共路由]
    I --> J[添加认证中间件 mw_auth.rs]
    J --> K[添加Cookie管理层]
    K --> L[添加静态文件服务]
    L --> M[启动HTTP服务器]
Loading

请求处理流程

flowchart TD
    A[HTTP请求] --> B[路由匹配]
    B --> C{是否需要认证?}
    C -->|是| D[认证中间件 mw_auth.rs]
    C -->|否| E[公共路由处理]
    D --> F{认证成功?}
    F -->|是| G[创建请求上下文 Ctx]
    F -->|否| H[返回401错误]
    G --> I[路由处理函数]
    E --> I
    I --> J[调用模型层 model/*.rs]
    J --> K[数据库操作 sqlx]
    K --> L[构建响应]
    L --> M[错误处理 error.rs]
    M --> N[日志记录 log.rs]
    N --> O[HTTP响应]
Loading

组件关系

flowchart TD
    A[main.rs] --> B[config.rs]
    A --> C[model.rs]
    A --> D[web.rs]
    A --> E[_dev_utils.rs]
    A --> F[error.rs]
    A --> G[log.rs]
    A --> H[ctx.rs]
    
    C --> C1[model/store.rs]
    C --> C2[model/ticket.rs]
    
    D --> D1[web/mw_auth.rs]
    D --> D2[web/routes_login.rs]
    D --> D3[web/routes_tickets.rs]
    
    E --> E1[_dev_utils/dev_db.rs]
Loading

环境变量加载流程

flowchart TD
    A[程序启动] --> B[config.rs::config]
    B --> C[config.rs::load_from_env]
    C --> D[config.rs::get_env]
    D --> E{环境变量存在?}
    E -->|是| F[返回环境变量值]
    E -->|否| G[返回错误 ConfigMissingEnv]
Loading

数据库初始化流程

flowchart TD
    A[_dev_utils::init_dev] --> B[dev_db::init_dev_db]
    B --> C[创建postgres数据库]
    C --> D[执行SQL初始化脚本]
    D --> E[返回数据库连接池]
Loading

认证流程

flowchart TD
    A[用户登录请求] --> B[routes_login.rs::api_login_handler]
    B --> C[验证用户凭据]
    C --> D[创建认证令牌]
    D --> E[设置AUTH_TOKEN cookie]
    E --> F[返回登录成功响应]
    
    G[受保护API请求] --> H[mw_auth.rs::mw_require_auth]
    H --> I[mw_auth.rs::mw_ctx_resolver]
    I --> J{AUTH_TOKEN cookie存在?}
    J -->|是| K[解析用户ID]
    J -->|否| L[返回401错误]
    K --> M[创建请求上下文 Ctx]
    M --> N[继续处理请求]
Loading

About

Rust Axum Production Coding

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published