15.1 项目架构设计

构建一个可维护、可测试且易于扩展的 Web 服务,关键在于合理的架构设计。本节将以一个典型的 RESTful API 项目(如任务管理服务)为例,介绍一种清晰的分层结构,将不同职责的代码分离到独立模块中,避免逻辑耦合。

整体分层结构

我们采用四层架构模型:

  • 入口层(main/bin):程序启动点,负责初始化配置、数据库连接、日志系统,并启动 HTTP 服务器;
  • 路由与传输层(handlers / routes):处理 HTTP 请求与响应,解析路径参数、查询字符串和请求体,调用应用服务,并格式化返回结果;
  • 应用服务层(services / app):包含核心业务逻辑,协调领域操作,不直接依赖 HTTP 或数据库细节;
  • 基础设施层(repositories / db / models):封装外部依赖,如数据库访问、缓存、第三方 API 调用等。

这种分层确保了核心业务逻辑与技术细节解耦,便于单元测试和未来替换底层实现(如从 SQLite 切换到 PostgreSQL)。

模块组织示例

假设项目名为 task_api,其目录结构可设计如下:

task_api/
├── src/
│   ├── main.rs                 # 入口:初始化并启动服务
│   ├── config.rs               # 配置加载与验证
│   ├── error.rs                # 统一错误类型定义
│   │
│   ├── handlers/               # 路由处理器
│   │   ├── mod.rs
│   │   └── tasks.rs
│   │
│   ├── services/               # 应用服务
│   │   ├── mod.rs
│   │   └── task_service.rs
│   │
│   ├── repositories/           # 数据访问
│   │   ├── mod.rs
│   │   └── task_repo.rs
│   │
│   └── models/                 # 领域模型与 DTO
│       ├── mod.rs
│       └── task.rs
│
├── migrations/                 # 数据库迁移脚本
└── Cargo.toml

各层职责说明

  • models:定义共享的数据结构,如 Task 实体、CreateTask 请求体、TaskResponse 返回体。这些类型被多层引用,但不包含行为。
  • repositories:实现对数据库的具体操作(如 create_task, find_by_id),通常通过 trait 抽象(如 TaskRepository),便于 mock 测试。
  • services:实现业务规则,例如“创建任务时自动设置创建时间”、“禁止修改已完成任务”。它依赖 repository trait,而非具体实现。
  • handlers:仅处理 HTTP 协议相关逻辑,如反序列化 JSON、调用 service、处理错误并返回 Json 或状态码。
  • main.rs:组合所有组件:读取配置 → 建立 DB 连接池 → 构建 repository → 注入 service → 注册 handler → 启动服务器。

依赖流向

依赖应单向流动:上层依赖下层,但下层不应知道上层的存在。例如:

  • handlers 依赖 services
  • services 依赖 repositoriesmodels
  • repositories 仅依赖 models 和数据库驱动;
  • 所有层均可依赖 errorconfig

通过 trait 抽象(如 dyn TaskRepository)或泛型注入,可进一步降低耦合。

小结

良好的架构不是过度设计,而是为变化预留空间。本节提出的分层结构在简洁性与可维护性之间取得平衡,适用于中小型 Web 服务。后续章节将基于此结构,逐步实现各层功能,展示如何在 Rust 中构建一个结构清晰、易于演进的生产级 API 服务。

#Rust 入门教程 分享于 5 天前

内容由 AI 创作和分享,仅供参考