🏛️ 后端架构模式(从单体到微服务全景)¶
学完具体 API 后,需要一层的"全局视野":后端项目是怎么组织起来的?REST / 分层 / 单体 / 微服务 / 消息驱动分别解决什么?本篇帮你在动手前先建立架构心智模型,避免"会写接口却不懂怎么搭项目"。
一、分层架构(最基础、必懂)¶
绝大多数后端项目都是分层的,请求自上而下穿过各层,每层只依赖下一层:
Controller(接请求/返回响应)
↓
Service(业务逻辑,核心)
↓
Repository / DAO(操作数据库)
↓
Database
- Controller:薄,只做参数解析、调用 Service、包装响应。不写业务。
- Service:业务逻辑都在这里,可单测、可复用。
- Repository:封装数据访问,屏蔽 SQL/ORM 细节。
分层反模式
- Controller 写业务:逻辑散在控制器里,无法复用、无法单测。
- Service 直接
req/res:业务层依赖 HTTP 框架,换传输层(如加 CLI/队列消费)就废了。Service 应只吃参数、吐数据。 - 跨层调用:Service 直接查 HTTP 头、Controller 直接
repo.save,破坏分层,后期重构痛。
二、RESTful API 设计¶
REST 是当前最主流的 HTTP 接口风格:用 资源(名词)+ HTTP 方法(动词) 表达操作。
| 方法 | 含义 | 示例 |
|---|---|---|
| GET | 查(幂等、安全) | GET /users/1 |
| POST | 增(非幂等) | POST /users |
| PUT | 整体改(幂等) | PUT /users/1 |
| PATCH | 局部改(幂等) | PATCH /users/1 |
| DELETE | 删(幂等) | DELETE /users/1 |
REST 设计要点
- URL 用复数名词资源:
/users而非/getUser;动作交给 HTTP 方法。 - 用状态码表意:200 成功、201 创建、204 无内容、400 参数错、401 未登录、403 无权限、404 不存在、500 服务端错。
- 分页/过滤用 query:
GET /users?page=1&size=20&role=admin。 - 版本化:
/api/v1/users,方便不破坏旧客户端地升级。
REST 常见错误
- 用 GET 做删除/修改(GET 应安全幂等,浏览器/代理可能预取、缓存,导致误删)。
- 把所有操作塞成
POST /doSomething,退化成 RPC,失去 REST 可预测性。 - 状态码永远 200,错误塞在
{code:500},前端只能解析 body,缓存/重试语义全乱。
三、单体(Monolith)vs 微服务(Microservices)¶
| 维度 | 单体 | 微服务 |
|---|---|---|
| 部署 | 一个包一次部署 | 多个服务独立部署 |
| 团队 | 小团队友好 | 多团队并行 |
| 复杂度 | 代码耦合风险 | 分布式复杂度(网络/事务/追踪) |
| 扩展 | 整体扩容 | 按需扩热点服务 |
| 适合 | 绝大多数项目、MVP、中小团队 | 大型、需独立扩容/独立技术栈 |
微服务决策红线
- 康威定律:微服务边界 = 团队边界。团队没拆分,强行拆服务只会内耗。
- 先模块化单体(Nest 的 Module 就是天然边界),等真的遇到"某模块要独立扩容 / 独立技术栈 / 团队大了"再拆。
- 微服务引入:服务发现、配置中心、分布式事务(Saga)、链路追踪、网关——每一项都是新运维负担。
四、消息驱动 / 事件驱动架构¶
用消息队列(Kafka/RabbitMQ/NATS)解耦生产者与消费者:
订单服务 → [下单事件] → 消息队列 → 邮件服务 / 库存服务 / 积分服务
- 好处:下单主流程不被"发邮件、减库存"拖慢;某个消费者挂了,消息不丢、恢复后补处理。
- 与 NestJS 进阶·队列 对应(BullMQ 是进程内队列,Kafka 是跨服务消息总线)。
何时用消息驱动
- 一个动作要触发多个后续副作用(下单→通知+扣库存+算积分)。
- 需要削峰(秒杀、批量导入)。
- 需要最终一致性而非强一致事务。
- 消费者必须幂等:同一条消息重投不能重复扣款/重复发邮件。
五、MVC / CQRS / 六边形(了解即可)¶
- MVC:Model(数据)+ View(视图)+ Controller(控制),早期 Web 全栈形态;后端 API 时代 View 退化为 JSON。
- CQRS(命令与查询职责分离):写模型和读模型分开,复杂读场景(报表/搜索)单独优化。高复杂度才上。
- 六边形架构(端口与适配器):业务逻辑在中心,外部(HTTP/DB/消息)通过"端口"接入,便于替换实现、利于测试。Nest 的 Provider/Interface 思路与之契合。
学习建议
新人先把分层 + REST + 模块化单体吃透,这覆盖了 90% 项目。CQRS/六边形是"遇到问题再引入"的进阶工具,不要提前过度设计。
六、一张图统筹:你的后端长什么样¶
┌─────────────┐
前端 ───▶ │ 反向代理 │ (Nginx: TLS/限流/静态)
└──────┬──────┘
▼
┌─────────────┐
│ Web 框架 │ (Express/Nest: 路由/中间件/Guard)
│ 分层架构 │
│ Controller │
│ Service │ ← 业务逻辑核心
│ Repository │
└──┬─────┬───┘
▼ ▼
┌────────┐ ┌─────────┐
│ DB │ │ Redis │ (缓存/队列/会话)
└────────┘ └─────────┘
│
┌─────┴──────┐
│ 消息队列 │ → 异步消费者/微服务
└────────────┘
- 想看运行细节 → Node.js 基础 / 高级 / 进阶
- 想看企业级框架落地 → NestJS 基础 / 高级 / 进阶
- 想看上线运维 → 部署与运维实战
- 想看避坑清单 → Node 最佳实践与反模式