Skip to content

108. 覆盖默认接口与并发更新演示

学习目标

这一节补齐 Vibe 系统后端的最后一块关键能力:让模块后端代码可以覆盖默认 CRUD 接口,并用并发更新演示后端代码的真实能力。

学完后,你应该能理解:

  • 自定义接口和默认接口有什么区别;
  • 为什么业务经常需要覆盖默认更新或删除逻辑;
  • 拦截器为什么不能解决所有业务规则;
  • 覆盖默认接口需要怎样的约定;
  • 技能文档为什么要同步更新;
  • 悲观锁如何解决并发更新问题。

默认接口的限制

通用模块默认提供增删改查接口。

这对普通后台页面已经够用。

但真实业务经常会有额外规则。

例如餐厅补贴或请假审批这类数据,如果状态已经是“已通过”,就不应该继续编辑或删除。

默认接口只知道怎么更新、删除数据,并不知道这些业务限制。

所以系统需要一种方式,让模块可以覆盖默认行为。

自定义接口和覆盖接口

自定义接口是额外新增的接口。

例如你新增一个 /special-delete,它和默认删除接口互不影响。

覆盖接口则不同。

它的目标是改变默认接口本身的行为。

例如用户仍然点击表格里的删除按钮,前端仍然调用默认删除路径,但后端执行时先检查模块后端代码里有没有覆盖逻辑。

如果有,就执行覆盖逻辑。

如果没有,就走默认删除。

这让前端交互保持不变,业务规则由模块后端代码接管。

拦截器的局限

前面通用 CRUD 已经有前置拦截器和后置拦截器。

它们可以在默认行为前后加逻辑。

但有些场景只靠拦截器不够。

例如你想完全替换更新或删除逻辑,或者想让 AI 写一段完整业务接口,这时更适合让模块后端代码声明覆盖函数。

可以这样理解:

  • 拦截器适合补充通用流程;
  • 覆盖接口适合替换默认流程;
  • 自定义接口适合新增额外能力。

覆盖接口的约定

课程里通过装饰器或类似约定来声明覆盖逻辑。

系统执行默认接口时,会先加载模块后端代码。

然后判断这段代码里是否声明了对应接口的覆盖函数。

例如:

  • 覆盖列表查询;
  • 覆盖单条查询;
  • 覆盖新建;
  • 覆盖更新;
  • 覆盖删除。

如果找到了覆盖函数,就执行它。

如果没有找到,就继续执行原来的通用 CRUD。

这样模块既能保留默认能力,又能在需要时接入特殊业务。

更新技能文档

后端支持覆盖默认接口以后,技能文档也必须更新。

否则 AI 不知道系统已经有新能力。

课程里特别强调技能名称和内容要写清楚:

  • 什么时候使用覆盖默认接口;
  • 每种覆盖函数有哪些参数;
  • 如何调用默认更新或默认删除;
  • 如何返回错误码和错误信息;
  • 哪些代码格式是系统能识别的。

这一步很容易被忽略。

但在 AI 系统里,代码能力变了,给 AI 的规则也必须同步变。

验证业务规则

示例里让 AI 生成覆盖逻辑:

已通过的数据不允许更新,也不允许删除。

保存模块后端代码后,再回到表格页面操作。

删除已通过数据时,系统会返回自定义错误信息。

删除未通过或其他状态的数据,则可以走正常流程。

更新已通过数据时,也会被拦住。

这说明默认接口已经被模块后端代码成功接管。

并发更新演示

课程最后用充值接口演示后端代码的能力。

同一条数据同时发起多个充值请求,例如分别加 1、2、3、4。

如果没有加锁,多个请求可能同时读到旧余额,再分别写回,最终结果就不一定等于加 10。

这就是并发更新问题。

带悲观锁的版本会在查询时锁住记录,让更新按顺序执行。

这样每次并发请求结束后,余额都会正确增加 10。

这个演示说明:模块后端代码不是玩具代码,它可以使用事务、锁和数据库会话,能力接近正常后端项目里的接口。

阶段重点

这一节让 Vibe 系统的后端能力完整起来。

前端可以生成页面和调用模块,后端可以新增自定义接口,也可以覆盖默认接口。

再加上技能发现和工具审批,AI 才能在受控范围内完成从建表、配置、页面到业务接口的完整开发流程。

AI Agent 课程学习文档。