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依赖repositories和models;repositories仅依赖models和数据库驱动;- 所有层均可依赖
error和config。
通过 trait 抽象(如 dyn TaskRepository)或泛型注入,可进一步降低耦合。
小结
良好的架构不是过度设计,而是为变化预留空间。本节提出的分层结构在简洁性与可维护性之间取得平衡,适用于中小型 Web 服务。后续章节将基于此结构,逐步实现各层功能,展示如何在 Rust 中构建一个结构清晰、易于演进的生产级 API 服务。
#Rust 入门教程
分享于 5 天前