真正做 Node.js 服务端时,你几乎不可能长期停留在原生 HTTP 层,但如果不了解框架解决了什么问题,也很难做出合理选择。这一篇会从原生能力起步,对比 Express、Koa、Fastify 和 NestJS 的思路差异与使用边界。
为什么原生 HTTP 通常不够?
Node.js 原生 HTTP 当然能写服务,但一旦项目稍微进入正式状态,你就很快会碰到这些重复问题:
- 路由分发怎么组织;
- 请求体和参数怎么解析;
- 中间件链路怎么挂;
- 错误和响应格式怎么统一;
- 团队多人协作时结构怎么保持稳定。
这也是框架存在的根本原因。它们不是为了替你“隐藏底层”,而是为了把重复的服务端基础设施收敛成更稳定的抽象。
但原生 HTTP 也不是毫无价值。恰恰相反,只要你亲手写过一次最基础的请求处理流程,就会更容易理解后面框架究竟帮你抽走了哪些重复工作:路由匹配、请求解析、响应封装、中间件串联、错误边界和插件扩展。知道这一层,你做选型时就不容易被“语法糖”迷惑。
几类主流框架的差异该怎么看?
你不需要一开始就把所有框架都学完,但至少要知道它们背后的取向。
Express
它更像一套轻量直接的服务端基础框架。上手快、生态广、思路直观,但结构约束相对较弱。项目越大,越需要团队自己维护边界和一致性。
Koa
它和 Express 一样偏轻量,但更强调中间件模型和更现代的抽象风格。对一些追求简洁和可组合性的团队来说会更舒服。
Fastify
它通常更强调性能和更清晰的插件体系,同时在校验、序列化等服务端基础能力上也更有组织感。它很适合那些既希望保留相对灵活性,又不想把所有基础设施都自己拼装一遍的项目。
NestJS
它更偏结构化和工程化。模块、依赖注入、控制器、服务这些概念都更明确,对大团队和大型系统很友好,但学习和约束成本也更高。
选型时真正该看什么?
框架选型最怕的就是只看流行度或者只看某一篇对比文章。更有价值的判断维度通常是:
- 项目规模;
- 团队经验;
- 需要多强的结构约束;
- 性能和插件体系要求;
- 长期维护成本。
换句话说,框架不是“哪一个最好”,而是“哪一个更适合当前问题和团队”。
如果再说得更具体一点,选型时通常至少要判断四件事:
- 你要的是“轻量自由”还是“结构先行”;
- 你更怕性能瓶颈,还是更怕团队失去一致性;
- 项目是偏快速迭代,还是偏长期平台化;
- 团队成员对抽象层级和约束强度的接受度如何。
这些问题比“某框架 benchmark 更快一点”更接近真实决策现场。
框架选择里最常见的误区是什么?
一个常见误区,是把框架当作对个人偏好的投票,而不是对项目约束的回应。比如:
- 因为流行就选,而不是因为适合;
- 因为上手快就长期停留在缺乏边界的结构里;
- 因为喜欢强约束,就把小项目也做成很重的架构;
- 只看短期开发体验,不看维护周期里的真实成本。
更稳妥的思路通常是:先承认没有万能框架,再围绕当前问题选择最小但够用的抽象。项目成长以后,再考虑是否需要更强的结构化能力。
如果以后要迁移,什么比“选对一次”更重要?
现实项目里,框架并不总是一开始就选到终点。所以,比“第一次就押中最终答案”更重要的,其实是:
- 不把业务逻辑过度绑死在框架细节上;
- 尽量保持接口层、服务层和数据层边界清楚;
- 让中间件、校验和响应模型有明确归属;
- 避免所有逻辑都堆进控制器或路由函数。
这样即便以后框架调整,迁移成本也会小得多。真正决定项目可持续性的,很多时候不是框架名称,而是你有没有把复杂度关进正确的边界里。
总结
这一篇先把 Node.js 服务开发里最常见的框架选择问题拉回到了更真实的语境:原生 HTTP 并不总够用,框架是在收敛重复问题,而不同框架的差异本质上是结构约束、性能诉求和团队协作方式的不同。
下一篇我们会继续顺着服务端主线往下走,先把中间件机制和请求生命周期这条链路讲清楚。