LOADING
1566 words
8 minutes
架构与路线图:Fastify + Prisma 全栈系列(零)

为什么架构决策值得单独写一篇

大多数后端教程默认你已经选好了框架、数据库、ORM。它们从 npm init 开始,跳过了一个最关键的步骤:你为什么选了这些技术。

选 Express 还是 Fastify?Prisma 还是 TypeORM?前后端放一起还是分开?这些问题没有标准答案——但选择的过程有迹可循。这篇建立一套判断框架,读完你未必会做出和我一样的选择,但你会知道从哪些维度来判断一个技术栈是否适合你的项目。


一、Node.js 框架选型:三个维度比跑分更有意义

Express、Fastify、Nest.js、Koa——四个框架都有大型项目在使用。很多人第一反应是看 Benchmark,但框架吞吐量的差异在大部分项目里不是瓶颈:数据库查询占了 80% 以上的请求耗时,框架本身的路由匹配和序列化开销只占很小一部分。

更有意义的判断维度是这三个:

约束力

Express 几乎没有约束。你可以把所有逻辑写在一个 app.js 文件里,路由顺序决定了鉴权范围。好处是灵活,代价是项目变大后,中间件的顺序变成隐式约定——新人不知道 app.use(auth) 应该放在哪些路由上方。

Nest.js 在另一个极端。Controller、Service、Module、Guard、Interceptor——每一层都有固定位置,依赖注入贯穿始终。好处是 50 人团队的新人写的代码和老员工风格一致,代价是装饰器封装得太厚:你不知道 @UseGuards() 到底对 HTTP 请求做了什么,只知道”加了它就有鉴权了”。

Fastify 在中间。插件系统强制你思考模块边界——一个插件不能访问另一个插件的内部状态,除非显式暴露。Hook 分为多个阶段(onRequestpreHandlerpreSerialization),每个阶段有明确语义。约束量刚好够用——不会让你写出意大利面条,也不至于让你变成配置工程师。

类型安全的内建程度

Fastify 的路由 Schema 不是附加的校验层——它就是路由定义的一部分。声明了 Schema 的路由自动校验请求和序列化响应,类型通过 Type Provider 传递到 Handler。Express 要实现同等效果需要 Zod + 手动类型推导 + 确保每个路由都调了 safeParse——能做到,但它是”外挂”的,能不能坚持全靠团队纪律。

生态质量

Express 的生态最大,但中间件质量参差——搜索 express middleware 能找到几百个包,其中很多已经两年没更新。Fastify 的核心插件由官方维护(@fastify/cors@fastify/jwt@fastify/cookie),数量少但每个都有维护者和明确的版本策略。

小结:如果项目只有 5 个端点、一个人维护,Express 最简单。如果 10+ 端点、多人协作,Fastify 的插件隔离和内置 Schema 校验减少团队摩擦。如果 50 人团队、需要严格架构约束,Nest.js 的 DI 体系从不自由变成了优势。


二、ORM 选型:Prisma vs TypeORM 的判断标准

Schema 是给人读的,还是给机器读的

Prisma 的 Schema DSL 设计初衷是作为”数据模型的可读文档”——打开 schema.prisma,所有表、字段、关系、约束一目了然。你可以把它打印出来跟同事讨论。TypeORM 的 Entity 类也能表达这些信息,但装饰器语法分布在多个文件里,没有一个俯瞰全局的视角。原生 SQL 的建表语句更难以作为设计讨论的素材。

类型安全是自动的还是手动维护的

Prisma 从 Schema 生成 Client,类型自动同步——改一行 Schema,不兼容的查询代码在编译期就报错。TypeORM 的 Entity 类需要手动和数据库表保持一致。你改了一个字段名但忘了同步 Entity 定义——编译通过,运行时抛错。

复杂查询时 ORM 是帮手还是绊脚石

Prisma 的一个清醒设计是它不试图取代 SQL。includeselect 覆盖 90% 的 CRUD 场景,复杂聚合查询和窗口函数走 $queryRaw 写原生 SQL。你需要复杂查询时不会被 ORM 的 API 限制住。

Migration 是否可追溯

Prisma 每次 migrate devprisma/migrations/ 下生成一个 SQL 文件。这些文件纳入 Git 后,数据库结构的完整演进过程有迹可查。TypeORM 也支持 Migration,但需要手动编写或半自动生成。

判断标准不是”谁是更好的 ORM”,而是”你的项目中,复杂查询的占比有多高”——如果超过 30%,Prisma 的抽象层可能开始成为负担,Query Builder + 原生 SQL 更合适。如果在 10% 以内,Prisma 的 Schema 可读性和自动类型生成是最强的优势。


三、Monorepo 的判断标准

不是”大厂都用 Monorepo 所以选它”。判断标准只有一个:你的前端和后端有没有共享类型。

如果有——比如 ApiResponse<T> 和错误码枚举需要前后端一致——Monorepo 的价值是立竿见影的。packages/contracts 被前端和后端以 workspace:* 引用,改了立刻生效,不一致在编译期就暴露。

多仓库方案下,共享类型的传递路径是”修改类型 → 发布到 npm → 前后端各自升级依赖”。这条链路对于小团队来说过重。复制粘贴则会在两周后产生两份”差不多但不一样”的类型定义。

如果没有共享代码,多仓库和 Monorepo 的差异不大,选你更熟悉的就行。


系列路线图

第 0 篇 ← 后端技术选型的判断框架
第 1 篇 → 后端项目的基础设施
第 2 篇 → HTTP API 设计的三层决策
第 3 篇 → 数据建模的核心决策
第 4 篇 → 查询设计的三个陷阱
第 5 篇 → 认证系统的四个硬骨头
第 6 篇 → 事务、并发与幂等

7 篇,不讲 Fastify 语法,不讲 Prisma API,不绑定任何具体项目——只讲后端设计中那些换了框架也不会变的判断和取舍。

架构与路线图:Fastify + Prisma 全栈系列(零)
/posts/2026-7-24/0-架构与路线图fastify--prisma-全栈系列/
Author
Atopos
Published at
2026-07-24
License
CC BY-NC-SA 4.0

Some information may be outdated