# 从 swagger_generator_flutter 迁移 [English](../MIGRATION.md) | [简体中文](MIGRATION.md) 本指南面向使用 `swagger_generator_flutter` 的 `generator_config.yaml` 惯例。 迁移应在消费方 Dart/Flutter 仓库中进行,不依赖任何本机绝对路径。 ## 建议顺序 1. 在独立分支保留旧生成结果; 2. 复制 [koi_swagger_parser.example.yaml](../../koi_swagger_parser.example.yaml), 第一轮只迁移 source、输出根和 response wrapper; 3. 第一次设置 `clean_stale_files: false` 并执行 `--dry-run`; 4. 生成到临时目录,对比 API signature、JSON key 和 import; 5. 迁移 enum、命名和 custom type mapping; 6. 在宿主项目运行 build_runner、`dart analyze` 和测试; 7. 审核输出后切换正式目录,并启用 `clean_stale_files: true`。 ## 可直接沿用 | 旧字段 | 新字段或行为 | |---|---| | `input.swagger_urls` | 同名;支持 string/object、`enabled`、本地路径和 HTTP(S) source | | `output.base_dir/api_dir/models_dir` | 同名 | | `output.included_tags/excluded_tags` | 同名,并支持 glob/正则 | | `output.split_by_tags` | 同名 | | `generation.api.client.class_name/file_name` | 同名 | | `generation.api.cancel_token_support` | 同名 | | `generation.api.base_result_import` | 兼容输入;选择 `external_generic` + `BaseResult` | | `generation.models.class_prefix` | 同名 | | `generation.models.json_serializable.*` | 同名 | | `generation.models.enum_key_mappings` | 仍然支持;建议迁移到 `enum_mappings` | | `formatting.run_dart_format` | 同名 | 已有 enum mapping 不需要立即重写: ```yaml generation: models: enum_key_mappings: TaskType: - value: 1 name: spotCheck description: 抽查 ``` 两个字段映射同一 wire value 时,`enum_mappings` 优先。生成器也识别 `x-enumNames`、`x-enum-varnames` 和 `x-enum-values`。 ## 需要改写 ### Response wrapper 旧写法: ```yaml generation: api: base_result_type: BaseResult base_result_import: package:app/network/base_result.dart ``` 推荐写法: ```yaml generation: api: response_wrapper: mode: external_generic detect_standard_envelope: true success_data_field: data external_generic: import: package:app/network/base_result.dart class_name: BaseResult ``` `base_page_result_type/base_page_result_import` 没有自动一对一迁移。优先在 OpenAPI 中准确描述分页 schema;复用已有类型时使用 `generation.mappings.schemas`,或用 `passthrough` 保留服务端 envelope。 ### 类型与 import mapping 旧顶层 `type_mapping` 和 `imports` 是全局配置。新配置把可校验 mapping 集中到 `generation.mappings`: ```yaml generation: mappings: schemas: Money: type: Money import: package:money2/money2.dart types: string:uuid: type: UuidValue import: package:uuid/uuid_value.dart string:date-time: DateTime imports: UuidValue: package:uuid/uuid_value.dart ``` type 查找先尝试 `type:format`,再尝试 `type`。`schemas` 表示 schema 完全由 external type 提供,不再生成对应 Dart model。 ### ignored directory/file 旧 `ignored_directories`/`ignored_files` 在渲染后跳过文件,可能留下引用缺失 model 的 API。应改为源语义 filter: ```yaml output: excluded_paths: - /api/v1/legacy/** excluded_operations: - regex:^internal excluded_models: - Legacy* ``` 保留的 operation 若依赖被排除 model,生成会以 `filter.required_model_excluded` 失败。没有任意丢弃渲染文件的设置。 ### 版本提取 `/api/v1/`、`/v2/` 等 path 会自动分组。若还要尝试从 source URL 提取: ```yaml output: extract_version_from_url: true ``` 旧 `generation.api.version_extraction.pattern/default_version` 没有一对一配置。 URL 提取失败会产生诊断并回到基于 path 的分组。 ### build_runner 旧流程通常单独执行 build_runner,现在可以并入生成: ```yaml formatting: run_dart_format: true run_build_runner: true build_runner_mode: build delete_conflicting_outputs: true ``` 交互式开发可用: ```bash dart run koi_swagger_parser generate --watch ``` watch 是长驻模式,不适合一次性 CI job。 ## 不再读取的旧设置 这些字段会产生 `config.unknown_key` warning: - `generator.name/version/author/copyright`; - `input.validate_schema/strict_mode`; - `output.api_file_suffix/model_file_suffix`; - `generation.api.use_dio/parser/method_naming`; - `generation.models.class_naming/field_naming/use_const_constructor`; - 顶层 `validation.on_error/on_warning`; - 顶层通用 import 排序/分组设置。 新生成器对会破坏 wire semantics 或编译的情况使用结构化 error,不提供 warn/ignore override。callbacks、links 等可安全省略的不支持结构使用 warning。 ## 需审核的生成代码差异 - readOnly/writeOnly schema 可拆为 `FooRequest`/`FooResponse`; - optional 但 schema 不允许 null 的字段仍用 nullable Dart argument 表示 absent, 同时使用 `disallowNullValue`;显式 JSON null 会被拒绝; - 根 object 同时有 `properties` 和 `additionalProperties` 时,extra 会 flatten 到 JSON 根; - `default` response 永不作为 success; - 复杂 parameter style 可产生 public transport adapter + private Retrofit delegate; - API method 可返回 `HttpResponse`,binary 输出可使用 bytes/stream; - enum 包含 wire conversion,unknown fallback 使用内部 sentinel wire value; - stale file 只通过 manifest ownership 删除;用户修改的 stale file 会保留。 ## CLI 对照 旧: ```bash dart run swagger_generator_flutter generate --all ``` 新: ```bash dart run koi_swagger_parser generate --all dart run koi_swagger_parser generate --dry-run --verbose ``` 旧 `--api`、`--models`、`--docs` 和 CLI tag override 不再保留。使用 `generation.*.enabled` 和 output filter。当前生成器不输出独立 API 文档站点。 ## 验收清单 - dry-run 无 error 诊断; - enum wire value 和 Dart member name 与旧契约一致; - request/response directional model 包含预期字段; - cookie、query、path 序列化产生等价请求; - error/default response 不被 decode 成 success; - external custom type 的 import 和 JSON conversion 正确; - `dart run build_runner build --delete-conflicting-outputs` 成功; - `dart analyze` 和宿主项目测试通过; - 第二次生成报告 `lifecycle.unchanged_skipped`; - 移除 operation 后只删除 manifest 拥有且未修改的文件。 对每个可用后端 fixture,除了对比生成源码,还应对比 runtime serialization。