法不净空,觉无性也。

第 36 章 实战案例一:从零构建带鉴权与限流的 API 网关

2026.08.29

36.1 拆解与蓝图设计

场景:从零构建一个带有鉴权(Auth)和限流(Rate Limit)机制的 API 网关核心逻辑。

这个场景浓缩了 AI 辅助编程中最经典的方法论问题:把"鉴权"和"限流"这两个横切关注点安排进正确的架构位置,并且保持它们之间的解耦——这是对"结构里程碑"和"逢混乱必重建"纪律的最佳演练场。

第一阶段:拆解(系统性降维)。

按照第 10 章的"系统性降维"原则,我们构建依赖树,明确实施的绝对先后顺序:

一期工程(打地基):JWT 鉴权中间件(核心,独立,最先做)
二期工程(建承重墙):限流中间件(依赖第一阶段的基础设施)
三期工程(拉水电):路由绑定与中间件组装(横向整合)

关键决策:第一期的里程碑仅为"完成 JWT 鉴权中间件",坚决不碰限流逻辑。把两个横切关注点拆成两个独立的结构里程碑,每个都可以独立验收。

蓝图设计要点(写入 CONTEXT.md):

  • 技术栈约束:Node.js + Express(或类似框架);JWT 解析库;限流驱动预留接口;
  • 数据模型:无数据库(中间件是纯逻辑),但需要定义 Token 载荷结构(user_id、exp、iat)、限流计数器的数据契约;
  • API 契约:中间件的输入(请求对象)与输出(请求对象 + 认证用户上下文 / 429 响应);自定义异常格式(401 AppError、429 RateLimitError);
  • 里程碑依赖树:M1 JWT 鉴权中间件 → M2 限流中间件 → M3 网关路由组装与集成验收。

导向性提示:在让 AI 写任何代码前,先把 CONTEXT.md 和验收标准交给它。M1 的验收标准示例:

验收标准(M1:JWT 鉴权中间件):
1. 解析 Authorization 头中的 Bearer Token;
2. 校验签名和过期时间,过期返回 401;
3. 校验通过后将 user_id 注入请求上下文;
4. 任何失败情况统一抛出 401 AppError;
5. Token 载荷中的敏感字段(如密钥)不得泄露到日志。

36.2 里程碑推进与验收

里程碑 M1:JWT 鉴权中间件。

  • 下发指令:把验收标准作为硬约束喂给 AI(验收驱动开发);
  • 编码:AI 生成中间件代码;
  • 验收:功能验收(用含有效/过期/伪造 Token 的请求逐一测试)、架构验收(中间件是否保持单一职责、没有偷偷引入不必要的库)、安全验收(没有把密钥硬编码、Token 载荷没有泄露敏感信息);
  • 结论:PASS → git commit 固化 → 更新 CONTEXT.md(记录 M1 完成、API 契约确定)→ 清空会话。

里程碑 M2:限流中间件。

  • 下发指令:明确技术约束——"限流逻辑必须保持为独立中间件,禁止与鉴权中间件耦合";
  • 编码:AI 生成限流逻辑;
  • 验收:功能验收(单位时间内超过阈值返回 429)、架构验收(是否依然解耦)、边界验收(并发场景、计数器重置);
  • 结论:PASS → commit → 更新蓝图。

里程碑 M3:路由组装与集成验收。

  • 将两个中间件按正确顺序挂载到网关路由;
  • 集成验收:鉴权失败不允许进入限流逻辑(短路);限流计数对已认证/未认证请求的处理一致;整体链路端到端测试通过。

36.3 一次故意的架构偏移:识别 → 升维指令 → 彻底重建

刻意制造一次架构偏移(这是第 10 章实操演练的完整版):

偏移的产生:向 AI 下发一个故意模糊的指令——"加上限流功能"(不提供任何技术约束)。AI 极大概率会判断"最简单的实现方式":直接在当前鉴权中间件文件里硬编码一段基于内存的限流逻辑。于是,鉴权和限流被死死耦合在了一起,文件开始膨胀。

识别信号(危险雷达报警):

  • 篡改地基:AI 修改了已固化的鉴权中间件文件(M1 已验收通过的里程碑);
  • 体积失控:单个中间件文件迅速膨胀。

升维指令(第一步纠错):不要指责细节,用架构语言指出结构缺陷:

"你刚刚的实现把限流逻辑硬编码在了鉴权中间件里,破坏了单一职责原则,且两个横切关注点被耦合。请将限流逻辑抽离为独立的中间件,保持模块解耦。"

叫停实施(第二步):如果 AI 陷入"自洽陷阱"——为了解耦而引入一个异常庞大且不兼容的第三方流控框架,甚至破坏了原本的路由绑定机制导致网关无法启动——连续两次纠错无效后,立刻叫停,不要第三次争辩。

彻底重建(第三步)

# 先检查当前分支和工作区,不执行恢复
git status --short
git log --oneline -5

先保护需要保留的已跟踪、未跟踪与忽略文件,再核实 M1 的完整目标哈希,并按第 10.4 节选择恢复路径:个人未共享分支才可考虑 reset;共享错误提交用 revert。stash 不是撤销,也不默认保护忽略文件;Git 不恢复数据库或外部系统状态。恢复后重跑 M1 验收,确认鉴权仍正确,再实施限流。

重建之后:重写 Prompt,细化限流机制的图纸指令——"使用内存计数器实现滑动窗口限流、维持中间件隔离状态、返回统一 429 格式"。然后清理已被污染的对话(/clear),将新图纸喂给全新的 AI 实例。

结果:新一轮出码不仅精准实现了功能,还完美维持了架构的优雅。

【复盘】每个决策点的心法

决策点心法
为什么第一期只做鉴权、坚决不碰限流?系统性降维——打地基时才决定地基,不要让 AI 跨越层级
为什么验收标准要在编码前就写好?验收驱动开发——验收标准是最好的指令,也是你的验收红线
为什么偏移发生后升维指令而不是微操?用架构师语言指出结构缺陷,给 AI 一两次自我修正的机会
为什么两次纠错无效后必须叫停?AI 已陷入自洽陷阱,继续纠缠只会污染上下文
为什么选择受控恢复后重建?按第 7.5 节比较含保护与验证的总成本,并按第 10.4 节恢复
为什么重建后要重开对话?切断 AI 的历史负面记忆,用干净上下文重新开始