Prepare the OpenAPI parser and Dart generator as a publishable Koi package with CLI entrypoint, docs, examples, tests, and pub.dev release metadata. Constraint: Initial GitHub import follows koi_blueprint_flutter identity mr.koi <i@mrkoi.is>. Rejected: Keep local runtime state in the initial repository | .dart_tool, .omx, and pubspec.lock are ignored for a reusable package source tree. Confidence: high Scope-risk: moderate Directive: Keep generated-output behavior covered by parser and generator tests before changing rendering rules. Tested: dart analyze; dart test; PUB_HOSTED_URL=https://pub.dev dart pub publish --dry-run Not-tested: End-to-end downstream build_runner compilation of generated Retrofit/Freezed output.
3.3 KiB
3.3 KiB
Architecture
koi_swagger_parser 采用“加载 -> 解析 -> IR -> 渲染 -> 落盘”的分层设计,避免把 OpenAPI 细节、Koi 业务约定、具体 Dart 输出模板揉在一起。
1. 分层
config
负责读取与归一化配置:
- 新配置:
koi_swagger_parser.yaml - 兼容配置:
generator_config.yaml - 路径归一化、默认值、旧字段兼容映射
- preset 解析(当前内置
koi_flutter)
openapi
负责:
- 本地/远程文档加载
- 多 source 深合并
- schema/ref 解析
- OpenAPI 3.1 nullable / anyOf / oneOf / additionalProperties / allOf 归一化
- multipart request body 与 discriminator union 识别
ir
产出与 OpenAPI 原文解耦的中间表示:
- API operation
- request body / parameter
- model / enum
- Dart type graph
IR 是后续接入 koi_blueprint_flutter preset 的关键。
generator
只关心如何把 IR 渲染成 Dart 文件:
- Retrofit API
- Freezed model
- enums
- index/client 聚合文件
这一层不直接处理 OpenAPI 细节。
preset
用于把 parser core 的 IR 和具体客户端技术栈解耦。当前先提供一个很薄的 preset 层:
koi_flutter:默认面向 Retrofit + Dio + Freezed- 当前主要控制 multipart 二进制字段该生成为
MultipartFile、File、Uint8List还是String - 后续可以继续扩展 blueprint preset、网络层 preset、命名/包装策略 preset
2. Response Wrapper 设计
parser core 不直接写死 BaseResult。
当前支持两种模式:
passthrough- 返回真实 OpenAPI response schema
- 适合你希望保留服务端 envelope 模型的场景
external_generic- 识别标准成功 envelope(默认
code/message/data) - 将
data提取为 inner type - API 返回
ExternalWrapper<Inner>,例如BaseResult<KoiStoreResponse>
- 识别标准成功 envelope(默认
这样做的意义是:
- parser core 保持通用
- Koi 网络层包裹策略可配置
- 未来可以挂更多 wrapper preset,而不是继续堆服务端补丁
3. 模型分组
模型按使用语义归档:
request/:只在请求体根节点使用result/:只在成功响应根节点使用shared/:被请求与响应共同依赖,或用于错误响应enums/:枚举单独分组
这比“按 swagger component 平铺”更符合 Koi 项目结构,也更利于未来蓝图模板整理。
4. 命名原则
- 类名统一 PascalCase。
- 字段统一 camelCase,并保留
@JsonKey(name: ...)对应 wire name。 - 文件名统一 snake_case。
- API 默认按
version + tag分文件。
命名转换统一收口到 util 层,避免每个阶段各写一套字符串处理逻辑。
5. 为什么新建项目而不是继续修补旧生成器
旧生成器的问题不是单点 bug,而是结构性耦合:
- OpenAPI 解析和业务输出绑定太深。
- nullable / anyOf / wrapper 规则分散在多个模板与解析阶段。
- 很难为未来
koi_blueprint_flutter抽出复用 IR。
所以这里直接重新收口:
- parser core 面向 OpenAPI 语义
- Koi 输出作为 renderer/preset
- 兼容旧配置,但不延续旧架构负担
6. 近期路线
- 第一阶段:打通 Koi/FastAPI 场景(已完成)
- 第二阶段:补齐 multipart、discriminator union、preset 基础层(当前版本)
- 第三阶段:扩更强 union fallback、更多 preset,并服务
koi_blueprint_flutter