Files
koi_swagger_parser/doc/ARCHITECTURE.md
T
mr.koi ea93f09154 Establish the Koi Swagger parser release
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.
2026-06-02 22:00:13 +08:00

115 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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>`
这样做的意义是:
- 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`