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

3.3 KiB
Raw Blame History

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