Files
koi_swagger_parser/doc/zh-CN/ARCHITECTURE.md
T
mr.koi 454e6c51d7 Release 0.2.0
Complete OpenAPI 3.0/3.1 generation, diagnostics, lifecycle safety, enum and naming mappings, bilingual documentation, examples, and pub.dev release validation.
2026-07-31 16:47:39 +08:00

155 lines
5.9 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.
# 架构
[English](../ARCHITECTURE.md) | [简体中文](ARCHITECTURE.md)
生成流水线有意拆分为多个阶段:
```text
配置
-> source loader
-> external/local $ref resolver
-> multi-source merger
-> validation + parser
-> transport/schema IR
-> preset + Dart renderer
-> manifest lifecycle
-> fix / format / build_runner
```
核心不变量是:加载阶段产生自包含且依赖可追踪的文档;parser 表达 OpenAPI
语义;renderer 不重新解释规范;lifecycle 只管理 manifest 中声明的文件。
## 配置
`lib/src/config/config.dart`:
- 查找 `koi_swagger_parser.yaml` 和兼容的 `generator_config.yaml` 名称;
- 相对 source/output 路径以配置文件目录解析;
- 从 `--cwd` 或显式配置目录确定宿主项目命令目录;
- 在转换 YAML scalar 前完成类型校验;
- 解析 enum、命名、type/import mapping 和 filter;
- 校验不支持的组合、mapping collision、正则和 enum mapping;
- 支持从旧 `base_result_import` 迁移。
未知 key 产生 warning;非法类型和不完整组合产生 error。详见
[配置参考](CONFIGURATION.md)。
## Loader、resolver 与 merger
对每个 root source,`OpenApiReferenceResolver`:
1. 规范化本地文件、file URL 或 HTTP(S) source;
2. 缓存每个加载的文档;
3. 解析 local、relative 和 remote `$ref`;
4. 把外部 component bundle 到根文档;
5. 为 component 冲突分配确定性名称;
6. 记录依赖并诊断无法支持的跨文档循环。
`OpenApiDocumentMerger` 再按配置顺序合并 root:
- 重复的 operation method/path 是 error;
- 同名但内容不同的 component 会确定性改名,并重写该 source 的 ref;
- 后输入不会静默覆盖冲突;
- 版本、info 和 path parameter 冲突会被报告。
parser 原则上只应收到根文档 JSON Pointer。仍然存在的 external ref 会被视为
resolver error。
## Validation 与 parser
`OpenApiDocumentParser` 负责:
- OpenAPI 3.0/3.1 版本和关键结构校验;
- operation、path、tag 和 model filter;
- parameter location、style、explode、`allowReserved` 和 `content`;
- request media type,以及 response status/content/header;
- server、security scheme 和 security requirement;
- required、nullable、readOnly/writeOnly 和 `additionalProperties` 语义;
- enum 配置/vendor extension 优先级;
- `allOf`、discriminator union 和已支持的 generic union;
- custom mapping 和 Dart 名称冲突。
无法用可靠 wire 语义渲染的结构不能静默退化为 `dynamic`。安全但有信息损失的
继续处理会产生 warning,例如不同成功 JSON body type 可能统一为 `Object?`。
XML、Protobuf 等没有已支持 decoder 的 media type 会产生 error。
## 中间表示
`lib/src/ir/ir.dart` 是 parser/renderer 契约,主要节点包括:
- `ApiOperation`:method、path、tag、version、server 和 security;
- `ApiParameter`:Dart/wire name、location、style、explode 和
`allowReserved`;
- `ApiRequestBody`:JSON、multipart、form-urlencoded 和 binary request;
- `ApiResponse`:status/default、body kind/type、content type 和 header;
- `ModelSpec`:object、enum、union model,以及 usage category 和 extras;
- `ModelField`:required/nullability/read-write flag 和 constraint;
- `DartType`:named、list、map、object、dynamic 和 void type graph。
model 按 request、result、shared、enum 分类。包含 readOnly/writeOnly 属性的
component 可投影为 request/response variant,避免 request 强制只读值,也避免
response 暴露 write-only secret。
generic `oneOf` 要求恰好一个 decoder 匹配。generic `anyOf` 保留 raw value 和
全部匹配 case。object 分支在 decode 前会用 required key 和 enum constraint
预筛。
## Preset 与 renderer
当前 `koi_flutter` preset 面向 Dio、Retrofit、Freezed 和 json_serializable。
renderer:
- 对 Retrofit 可表达的 parameter 形式使用 Retrofit annotation;
- 当已支持的 style、cookie 或 `allowReserved` 组合需要自定义序列化时,生成
typed public adapter 和 private Retrofit delegate;
- 渲染 Freezed object、enum 和 union model;
- 为根级 `properties` + `additionalProperties` 渲染自定义 map 读写 helper;
- 收集 model dependency 和 external type import;
- 按 version/tag 分组 API,并输出 client/index 文件。
renderer 不加载 ref,也不判断 OpenAPI 结构是否合法。
## 生成生命周期
落盘前,`GenerationLifecycle` 计算:
- canonical merged spec SHA-256;
- normalized config SHA-256;
- 每个渲染 path/content SHA-256。
manifest 记录 schema/generator version、source root、dependency 和每个主生成
文件的实际 hash。写入使用操作系统 exclusive lock 和同目录临时文件 rename。
安全不变量:
1. renderer 输出必须位于配置的 API/model 根;
2. stale candidate 必须来自旧 manifest;
3. stale path 仍必须位于当前 managed root;
4. 删除前当前 hash 必须等于旧 manifest hash;
5. 损坏或未知版本 manifest 不参与删除;
6. fix/format/build 失败时不写 success manifest;
7. watch 在释放生成锁后启动。
`.g.dart` 和 `.freezed.dart` 由 build_runner 管理,不进入本生成器的 stale
manifest。
## Response wrapper
parser 不硬编码 `BaseResult`:
- `passthrough` 返回 OpenAPI response schema;
- `external_generic` 检测配置的成功 envelope,并返回
`ExternalWrapper<Inner>`。
`default` response 仍是错误响应。`response_mode: http_response` 保留 Dio
status/header。错误 response model 仍保留在 IR 和生成 model 集合中。
## 扩展边界
IR/preset/renderer 分层为未来的版本化 renderer interface、template override、
semantic diff 和可选 runtime adapter 留出空间。这些是设计方向,不是当前
公开版本的功能。当前实现边界见[兼容性](COMPATIBILITY.md)。
更多生态对比属于项目内部调研,不随发布 package 交付。