摘要:本文基于 Sourcelin Blog 项目的实践经验,探讨了在长期维护的项目中,接口契约管理的重要性。文章指出,如果接口协议没有明确收口,AI 在前后端联调时可能会“乱猜”接口结构(如成功码、分页字段等),导致高返工率。作者通过制定明确的 API 契约规则(如固定成功码为 0、统一分页字段),并将其提前“喂给”AI,显著提升了 AI 在联调任务中的稳定性和效率。文章还分享了如何在后端(Java)和前端(TypeScript)中体现这套契约,并提供了判断 AI 是否真正遵守契约的实用标准。最后强调,对于长期项目,协议收口比临时兼容更重要。

只要一个项目准备长期维护,接口契约就不能靠“临时记忆”和“页面兜底”维持。
这件事我在 Sourcelin Blog 里踩过坑之后,感受特别深。

很多人会觉得 AI 最擅长的是补代码,但我后来更看重它能不能遵守协议。
一旦协议没收口,AI 每做一轮前后端联调,都可能重新猜一次接口结构。

我在这个项目里对 AI 最大的一个体感变化,不是它会不会写代码,而是它什么时候开始“不再乱猜接口结构”。

只要接口协议没收口,AI 每做一轮前后端联调,都可能重新猜一次:

  • 成功码是 0 还是 200
  • 列表字段读 items 还是 rows
  • 分页参数叫 pageSize 还是 limit

这类问题看起来小,但返工特别高。

Sourcelin Blog 里,这层规则已经被写死了

rules/api-contract.md 里,核心约束非常明确:

- MUST:对外 REST JSON 成功响应统一为 ApiResponse<T>
- MUST:成功码固定为 0
- MUST:分页字段固定为 items、total、page、pageSize、totalPages
- MUST NOT:前端使用 items ?? list、items ?? rows、items ?? records

我后来越来越觉得,这类规则必须提前喂给 AI。
否则它每次都可能“兼容性很好”地帮你写出一堆历史包袱。

后端怎么体现这套契约

博客后台文章列表返回就是标准分页:

public PageResult<ArticleVO> list(Article article)
{
    PageDomain pageDomain = TableSupport.buildPageRequest();
    PageHelper.startPage(pageDomain.getPage(), pageDomain.getPageSize());
    List<ArticleVO> list = articleService.selectArticleVoList(article);
    PageInfo<ArticleVO> pageInfo = new PageInfo<ArticleVO>(list);
    return BlogPageResults.of(list, pageInfo);
}

这里最关键的不是 PageHelper,而是最终返回的是 PageResult<ArticleVO>

前台 API 怎么消费这套契约

前台文章 API 已经明确用 PageResult<ArticleListItem> 了:

export function getArticles(params: ArticlePageQuery) {
  return requestData<PageResult<ArticleListItem>>({
    url: '/front/articles',
    method: 'get',
    params
  })
}

这意味着页面和 composable 就该直接消费:

  • items
  • total
  • page
  • pageSize
  • totalPages

而不是再去写一层旧字段兜底。

我现在怎么把这件事交给 AI

请在 Sourcelin Blog 中完成一个前后端联调相关任务。
必须先阅读 rules/api-contract.md。

要求:
1. 后端对外接口统一返回业务对象、PageResult、ListResult、IdResponse 或 Void
2. 前端页面只消费 request 层解包后的业务数据
3. 分页字段只允许 items/total/page/pageSize/totalPages
4. 不允许保留 rows/list/records 的 fallback

有了这层提示,AI 在联调类任务里的稳定性会明显提升。

为什么我不再接受“兼容旧字段”的写法

因为它会让项目一直维持在一种模糊状态:

  • 旧字段还能用
  • 新字段也能用
  • 页面看起来没问题
  • 但真实协议永远收不拢

这在短期项目里可能还能忍,但只要项目准备长期维护,越早收口越好。

一个很实用的判断标准

如果你想知道 AI 这一轮有没有真正遵守契约,可以直接问它三件事:

  1. Controller 返回类型是什么
  2. 前端 API 类型声明是什么
  3. 页面最终消费的分页字段是什么

只要这三层对不上,后面大概率还会返工。

接口返回结构
列表页分页效果

这类任务里 AI 最容易跑偏的点

  • 偷偷写兼容旧字段的 fallback
  • 页面里还在判断 code === 200
  • 后端返回旧响应结构,但前端靠兜底“跑起来了”

我现在很少再把“能跑”当成联调成功。
对一个长期项目来说,真正重要的是协议有没有收口,而不是有没有临时兼容过去。这种东西写成文章,往往比单纯晒功能更有价值。

项目地址

  • 在线演示:https://sourcelin.cn
  • Gitee:https://gitee.com/my_lyq/sourcelin-cloud-blog
  • GitHub:https://github.com/SourceLin/sourcelin-cloud-blog

如果你刚好在找一个:

  • 微服务博客系统
  • Spring Cloud Alibaba 实战项目
  • Vue 3 + Java 全栈项目
  • 毕设 / 课程设计参考项目
  • 支持 AI 协作开发的开源仓库

可以看一下这个项目。欢迎试用、提 Issue,也欢迎点个 Star 支持一下。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐