在Django项目里,"这个字段前端真的在用吗"是个让人头疼的问题。你得查后端、翻React代码、再问可能知情的人。答案永远散落在某处,却从不在一个地方。没人粗心,只是缺一份契约。
我的技术栈是Go后端配Flutter前端。确定现在的方案前,加个接口意味着双倍工作量:先在Go里定义请求响应结构、接handler、加中间件;再在Dart里重复整个模型层,用Dio包层repository才能调用。每次改动都交同样的税,单笔不大,复利惊人。
我最终采用的方案本身不新鲜:从OpenAPI规范生成代码。但让它真正跑通,花了几个项目才磨合好。这份规范不是文档,而是所有代码编译依赖的单一制品——人类判断、编译器约束、LLM推理,都在实现之前在此交汇。
多数OpenAPI教程把规范当成代码的副产品,或需要并行维护的文档。我经过三个项目反复验证的路子正好相反:先写规范,从它生成一切,绝不让代码偏离规范。
这能跑通,是因为OpenAPI结构化、可校验,且在LLM训练数据里存在感很强。我让模型设计接口时,它写OpenAPI YAML的可靠性远高于直接写地道Go或Dart。规范自然成了交接点:人类审阅、编译器强制执行、LLM在契约敲定前绝不碰实现。
第一次正经尝试是在Flutter项目。Dart默认强类型,手动对齐Go结构和Dart模型的摩擦从一开始就显而易见。我在两边都搭了代码生成,缺口堵上了。启动当前项目(一个研究院ERP)时,这成了起点而非实验。
单体仓库结构很关键。所有东西必须放在一起,因为规范得是跨消费者的唯一真相源。
目录结构长这样:api/services/下按业务拆成23个yaml文件,redocly合并成openapi.yaml,还有给LLM用的自动导航索引。backend/gen/api/和frontend/packages/shared_api_client/lib/各自镜像这套拆分,每个服务有自己的codegen配置和生成脚本。
规范即契约的玩法,本质是让人机协作有了仲裁标准。LLM擅长写规范,人类擅长审规范,编译器擅长守规范——各干各的强项,不再互相踩脚。
热门跟贴