Express 编写后端服务整套技术栈怎么选:主流方案、分层落地与面试答法
面试速答(30 秒版 TL;DR)
- 现在用 Express 搭后端,主流思路不是“只装一个框架就开写”,而是围绕 Web 框架、类型系统、数据库访问、缓存、鉴权、校验、日志、部署 组成一套工程方案。
- 中小团队最常见的一套组合是:TypeScript + Express + Prisma + MySQL/PostgreSQL + Redis + JWT + Zod/Joi + Pino + Docker + Nginx。
- Express 负责 HTTP 接入和中间件编排,真正决定项目能不能长期维护的是:分层是否清晰、错误模型是否统一、配置是否收口、运行治理是否补齐。
- 如果面试官追问“为什么它流行”,核心原因是:Express 足够轻、生态成熟、接第三方库方便,适合自己按业务复杂度自由组装。
- 一句话总结:Express 本身只是入口,热门方案的重点在于围绕它补齐数据层、缓存层、鉴权层和运维层。
心智模型:先把“整套技术栈”拆成 8 层
很多人回答这个题,会把它说成“Express + MySQL + Redis”。
这不够,因为面试官想听的是你是否有完整工程视角。
更稳的回答方式是拆成下面 8 层:
- 接入层:Nginx、HTTPS、反向代理、限流
- 应用层:Express、Router、中间件
- 业务层:Controller、Service、领域规则
- 数据层:Prisma / Sequelize / TypeORM、MySQL / PostgreSQL / MongoDB
- 缓存层:Redis
- 安全层:JWT / Session、权限校验、参数校验
- 观测层:日志、监控、链路追踪、健康检查
- 交付层:Docker、CI/CD、PM2 / 容器编排
只要你能按这个模型讲,回答就已经从“会写接口”升级成“会搭服务”。
一、最常见的主流方案是什么
如果是面试里让你给一套“Express 编写后端服务的热门方案”,最推荐先给出一个默认基线:
| 层次 | 主流选型 | 为什么常见 |
|---|---|---|
| 语言 | TypeScript | 降低大型项目维护成本,接口和 DTO 更清晰 |
| Web 框架 | Express | 轻量、成熟、生态老牌、上手成本低 |
| ORM / 数据访问 | Prisma | 类型友好、开发体验好、和 TS 配合自然 |
| 关系型数据库 | MySQL / PostgreSQL | 业务系统主流,事务、索引、查询能力稳定 |
| 缓存 | Redis | 缓存、分布式锁、限流、会话共享都常用 |
| 鉴权 | JWT + Refresh Token | 前后端分离项目里很常见 |
| 参数校验 | Zod / Joi | 统一校验请求参数,避免脏数据进入业务层 |
| 日志 | Pino / Winston | 收敛访问日志和错误日志 |
| API 文档 | Swagger / OpenAPI | 前后端联调和接口维护成本更低 |
| 测试 | Jest / Supertest | 覆盖单测和接口测试 |
| 部署 | Docker + Nginx | 部署标准化,反向代理和静态能力成熟 |
如果只允许你说一句推荐方案,可以直接答:
我会优先用 TypeScript + Express + Prisma + MySQL 或 PostgreSQL + Redis + JWT + Zod + Pino + Docker,这是一套现在中后台场景里很常见、工程成本和灵活性都比较平衡的组合。
二、为什么 Express 还能成为热门方案
很多人会问:NestJS、Koa、Fastify 都很火,为什么 Express 还常见?
核心原因有 4 个:
1. 生态成熟
- 很多 Node 中间件首先支持 Express 生态。
- 招人、交接、排障、搜索资料的成本都比较低。
2. 足够轻
- Express 不强行规定你的 ORM、鉴权、日志方案。
- 小项目可以轻装上阵,大项目也能逐步补基础设施。
3. 历史项目存量大
- 很多公司旧项目就是 Express。
- 新项目即使不用 Express,本质设计也常参考它的中间件模型。
4. 对“自己组装技术栈”的团队很友好
- 如果团队不想被框架强约束,Express 的自由度很高。
- 它特别适合作为“基础 HTTP 容器”。
所以它流行的本质不是“它最先进”,而是:
- 它足够通用、足够成熟、足够容易和各种热门库组合。
三、一套完整 Express 技术栈在请求链路里怎么协同
先记请求主链路:客户端 -> 网关 -> Express -> 中间件 -> Controller -> Service -> 缓存 / DB -> 响应。
这张图想表达的重点是:
- Express 不是孤立存在的,它通常处在网关之后、数据库之前。
- Redis 和数据库不是二选一,而是经常同时存在。
- 业务复杂后,请求链路里还会引入异步任务和队列。
四、主流组合怎么选,不同场景答案不一样
方案 A:中后台业务系统最常见
推荐组合:
TypeScriptExpressPrismaMySQL或PostgreSQLRedisJWTZodPinoDocker + Nginx
适用场景:
- 管理后台
- 电商中后台
- SaaS 业务系统
- 常规 CRUD 较多的服务
为什么它最常见:
- 关系型数据库适合订单、用户、权限、配置这类强结构数据。
- Prisma 和 TS 配合顺手,开发体验好。
- Redis 可以补缓存、验证码、登录态、限流。
方案 B:内容型或弱结构数据较多
推荐组合:
TypeScriptExpressMongoose或 MongoDB 原生驱动MongoDBRedis
适用场景:
- 内容平台
- 文档类产品
- 字段变化快、结构弹性大的业务
注意点:
- MongoDB 不是“省设计”,而是“换一种建模方式”。
- 一旦关联复杂、事务要求高,关系型数据库往往更稳。
方案 C:高吞吐、追求更强性能
常见组合会演进成:
- 保留 Express 作为管理端或兼容层
- 新服务改用
Fastify - 数据层继续用
PostgreSQL / MySQL + Redis
面试里这时不要说 Express 不能用,而要说:
- Express 可以满足绝大多数业务需求,但如果系统明确追求更高吞吐、更低框架开销,团队可能会转向 Fastify。
五、每一层通常怎么落地
1. Router 层
职责:
- 绑定 URL 和 HTTP 方法
- 挂载中间件
- 把请求转给 Controller
不要做的事:
- 不要在路由层写业务判断
- 不要在路由层直接查数据库
2. Controller 层
职责:
- 接住 HTTP 参数
- 调用 Service
- 统一响应格式
它处理的是“协议适配”,不是核心业务。
3. Service 层
职责:
- 实现业务规则
- 编排数据库、缓存、外部服务
- 处理事务、幂等、重试
这一层才是系统的业务中枢。
4. Repository / ORM 层
职责:
- 统一数据库读写
- 收口查询细节
- 屏蔽底层实现差异
面试里可以直接总结为:
- Router 决定怎么进,Controller 决定怎么收发,Service 决定业务怎么做,Repository 决定数据怎么取。
六、热门技术栈里最容易被追问的几个点
1. 为什么现在很多 Express 项目会配 TypeScript
因为 Express 本身很灵活,灵活带来的问题是:
- 参数结构容易散
req上扩展字段容易失控- DTO、返回值、错误结构容易不统一
TypeScript 的价值不是“更高级”,而是:
- 在 Express 这种自由框架里补类型约束。
2. 为什么很多人从 Sequelize / TypeORM 转到 Prisma
常见原因:
- Prisma 的类型提示体验更好
- schema 驱动开发更清晰
- 和 TypeScript 集成更自然
但更严谨的说法是:
- Prisma 很适合中后台常规业务。
- 如果要极致 SQL 控制、复杂查询调优,团队也可能保留原生 SQL 或 query builder。
3. Redis 在整套方案里通常负责什么
最常见的 4 类职责:
- 缓存热点数据
- 存验证码、登录态、临时状态
- 做限流、计数器、分布式锁
- 作为异步任务的轻量协作组件
4. JWT 为什么常见,但又不是银弹
它常见是因为:
- 前后端分离方便
- 服务无状态扩容更容易
它的问题也要会讲:
- token 失效控制更复杂
- 权限变更后的即时收敛较弱
- 刷新 token、黑名单、登出机制都要自己补
这类回答会比“JWT 很方便”更像工程答法。
七、给一套可落地的推荐目录结构
src/
app.ts
server.ts
config/
common/
errors/
logger/
middleware/
modules/
user/
user.route.ts
user.controller.ts
user.service.ts
user.repository.ts
user.schema.ts
prisma/
jobs/
tests/
这种结构背后的思路是:
- 公共能力放
common - 业务按模块拆分
- 每个模块自己收口 route、controller、service、repository、schema
它比“按 controllers / services / models 全局横切拆目录”更适合业务持续变大。
八、面试里可以直接复述的一套标准答法
如果面试官问“你会怎么用 Express 搭一套主流后端技术栈”,可以这样答:
- 我会先用 TypeScript + Express 搭 HTTP 层,因为 Express 轻量,生态成熟。
- 数据层优先选 Prisma 配 MySQL 或 PostgreSQL,适合中后台主流业务。
- Redis 负责缓存、限流、验证码、分布式锁这类高频能力。
- 鉴权一般用 JWT + Refresh Token,参数校验用 Zod 或 Joi。
- 日志用 Pino 或 Winston,接口文档用 Swagger/OpenAPI。
- 代码分层按 router、controller、service、repository 拆,错误处理和日志通过中间件统一收敛。
- 部署层用 Docker + Nginx,补健康检查、监控、优雅退出。
这套回答的优点是:
- 有主流选型
- 有选型理由
- 有工程治理
- 有落地分层
九、一个最小可运行的技术栈示例
下面这个例子不追求“大而全”,只表达分层和依赖关系:
import express from 'express'
import jwt from 'jsonwebtoken'
import { z } from 'zod'
const app = express()
app.use(express.json())
const createUserSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
})
app.post('/users', async (req, res, next) => {
try {
const input = createUserSchema.parse(req.body)
const token = jwt.sign({ role: 'user' }, process.env.JWT_SECRET!, {
expiresIn: '1h',
})
res.status(201).json({
user: input,
token,
})
} catch (error) {
next(error)
}
})
这个例子要说明的不是业务完整,而是:
- Express 负责接请求
- Zod 负责参数校验
- JWT 负责令牌签发
- 错误统一进入中间件
真实项目里还会继续拆到 Controller、Service 和 Repository。
典型题与标准答法
1. 为什么 Express 项目很少只谈 Express 本身
- 因为后端服务不是只靠框架就能成立。
- 真正的完整方案一定包含数据库、缓存、鉴权、日志、部署和监控。
2. Express 搭后端,数据库优先选 MySQL 还是 MongoDB
- 如果是强结构、事务要求高、关联关系明显的业务,优先 MySQL 或 PostgreSQL。
- 如果是文档型、字段变化快、结构更灵活的业务,MongoDB 更合适。
3. 为什么 Redis 几乎是标配
- 因为它不只是缓存,还承担共享状态、限流、锁、验证码和热点数据加速。
4. 为什么热门方案里经常会出现 TypeScript
- 因为 Express 自由度高,TS 能补齐接口边界和协作约束,项目越大越明显。
5. Docker + Nginx 为什么常和 Express 一起出现
- Docker 解决环境一致性和交付标准化。
- Nginx 解决反向代理、TLS 终止、静态资源、压缩和限流入口。
常见追问
1. Express 和 NestJS 怎么选
- 如果团队想要更强约束、模块化和依赖注入,NestJS 更省心。
- 如果团队想自己组装技术栈、保持轻量和自由,Express 更灵活。
2. Prisma 和原生 SQL 是对立关系吗
- 不是。
- 常见做法是大部分 CRUD 用 Prisma,复杂热点查询保留原生 SQL。
3. JWT 和 Session 谁更好
- 没有绝对谁更好。
- 前后端分离、跨端较多时 JWT 常见;单体后台、服务端渲染项目里 Session 也很稳。
4. Express 项目一定要上微服务吗
- 不一定。
- 多数团队一开始是单体或模块化单体,业务复杂后再拆分。
易错点
- 把“整套技术栈”答成“Express 怎么写路由”。
- 只会背框架名,说不出每个组件解决什么问题。
- 把缓存、鉴权、参数校验都堆进 Controller。
- 只讲开发,不讲日志、监控、健康检查、优雅退出。
- 看到热门就盲选,不结合业务数据模型和团队能力。
速记要点
- 主流基线:
TypeScript + Express + Prisma + MySQL/PostgreSQL + Redis + JWT + Zod + Pino + Docker + Nginx - Express 是 HTTP 入口,不是全部架构。
- 技术栈选择要围绕数据模型、团队经验、性能目标、维护成本。
- 代码分层通常是
router -> controller -> service -> repository - 一套成熟方案必须补齐校验、鉴权、日志、监控、部署治理