
TypeSpec OpenAPI3 发射器演进全解从 OpenAPI 3.0 到 3.2 的核心能力与配置指南【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespec本指南以 packages/openapi3/CHANGELOG.md 为骨架系统梳理typespec/openapi3包从 0.2.0 到 1.16.0 的能力演进它既负责把 TypeSpec 服务定义发射emit为 OpenAPI 3.0/3.1/3.2 文档又内置tsp-openapi3命令行工具把既有 OpenAPI 文档反向转换为 TypeSpec。读完本文你将掌握该发射器的全部核心配置项enum-strategy、operation-id-strategy、file-type、openapi-versions等、关键装饰器与安全认证模型以及 OpenAPI ↔ TypeSpec 双向转换的完整能力边界并能在真实项目中直接落地这些配置。一、版本脉络从单一 3.0 输出到多版本并行发射typespec/openapi3的演进史本身就是一条「OpenAPI 规范支持能力」的扩展史0.2.02021-09首个 OpenAPI 3.0 发射器诞生同时移除多重继承支持0.64.0引入openapi-versions发射器选项正式支持发射 OpenAPI 3.1 模型默认仍输出 3.01.6.0加入 OpenAPI 3.2.0 发射支持并支持 SSEServer-Sent Events的发射与导入1.9.0在 3.1.0 与 3.2.0 均已实现的基础上将openapi-versions选项正式公开稳定。从源码结构看不同版本对应独立的 schema 发射实现packages/openapi3/src/schema-emitter-3-0.ts、schema-emitter-3-1.ts、schema-emitter-3-2.ts以及配套的openapi-helpers-3-0.ts/openapi-helpers-3-1.ts说明 3.0 与 3.1/3.2 在 JSON Schema 语义上走的是两套渲染路径。这一点在后面的enum-strategy与$ref处理中会体现得尤为明显。二、发射器核心选项详解全部选项的类型定义、JSON Schema 校验与默认值都集中在 packages/openapi3/src/lib.tsEmitterOptionsSchema起始于第 144 行README 中的权威说明见 packages/openapi3/README.md。配置方式有两种CLI 直接指定或写入tspconfig.yaml。# 方式一命令行 tsp compile . --emittypespec/openapi3 # 方式二tspconfig.yaml emit: - typespec/openapi3 options: typespec/openapi3: enum-strategy: annotated2.1output-file输出文件名插值默认值{service-name-if-multiple}.{version}.openapi.yaml若file-type为json则后缀为.json当file-type为数组时使用{service-name-if-multiple}.{version}.openapi.{file-type}。支持插值的变量有变量含义service-name服务名。自 0.66.0 起总是插值当前服务名service-name-if-multiple仅当存在多个服务时才插值服务名0.66.0 起用于替代旧行为version服务的版本多版本时file-type正在发射的文件类型json/yaml在file-type为数组时尤其有用典型命名效果单服务无版本openapi.yaml多服务无版本openapi.Org1.Service1.yaml、openapi.Org1.Service2.yaml单服务带版本openapi.v1.yaml、openapi.v2.yaml1.16.0 的安全修复值得一提output-file中插值的{version}、{service-name}、{service-name-if-multiple}现在会经过路径净化sanitize确保版本号或命名空间名中若包含路径分隔符也无法把 OpenAPI 文档写出发射器输出目录之外。源码实现见 packages/openapi3/src/openapi.ts 的resolveOutputFile函数——它对每个插值片段调用编译器提供的sanitizePathSegment后再交给interpolatePath完成路径拼接。2.2file-typeYAML/JSON 输出格式类型yaml | json | (yaml | json)[]默认yaml未指定时从output-file扩展名推断。1.10.0 起支持传入数组在同一次运行中同时产出 JSON 与 YAML 两种格式——配合output-file中的{file-type}变量即可生成互不覆盖的两个文件。2.3openapi-versions目标规范版本类型3.0.0 | 3.1.0 | 3.2.0的数组默认[3.0.0]。当指定多个版本时输出文件会写入以各规范版本命名的子目录。这也是 3.1 与 3.2 的unevaluatedProperties、$ref兄弟关键字等新语义得以触发的开关。2.4enum-strategy枚举发射策略类型default | annotated默认default。这是 1.14.01.15.0 连续两个版本打磨出来的重点特性default把枚举折叠为单一 schema使用enum关键字信息有损成员注释丢失annotated遵循 OpenAPI 3.1.1 的「注释枚举」annotated enumerations模式把枚举发射为oneOf的const子 schema 数组每个子 schema 带title/description取自成员上的summary/doc。options: typespec/openapi3: enum-strategy: annotated对enum类型1.14.0 引入与字面量联合union1.15.0 扩展anyOf或oneOf均生效。例如/** Type of pet. */ enum PetType { /** A loyal canine companion. */ summary(Dog) Dog: dog, /** A self-sufficient feline. */ summary(Cat) Cat: cat, }发射结果PetType: description: Type of pet. oneOf: - const: dog title: Dog description: A loyal canine companion. - const: cat title: Cat description: A self-sufficient feline.注意约束annotated仅支持 OpenAPI 3.1.0 及以上在 3.0.0 下会自动回退到default形式并报告警告。1.15.0 还允许对联合使用oneOf装饰器把默认的anyOf切换为oneOf见下例联合变体携带 URL 字面量与summary注释/** Set of known error types. */ union ErrorType { /** Common error for a bad request. */ summary(CommonBadRequest) commonBadRequest: https://example.com/errors/bad-request, /** The request body could not be parsed. */ summary(InvalidBody) invalidBody: https://example.com/errors/invalid-body, }2.5operation-id-strategyoperationId 生成策略1.5.0 引入决定未显式使用operationId时如何生成operationId默认parent-container取值行为parent-container将操作名与父容器命名空间/接口名以下划线连接默认与历史行为fqn从服务根到操作的全限定名以.连接noneCLI/explicit-only配置不生成 operationId仅保留显式operationId配置还支持对象形式{ kind, separator }用自定义separator替换连接符。同版本修复了「解析到相同 operationId 时去重」的问题。其独立实现见 packages/openapi3/src/operation-id-resolver/operation-id-resolver.ts并配套了专门的单元测试文件。2.6 其余选项速查选项类型/默认说明引入版本safeint-strategyint64/double-int默认int64控制safeint标量输出为format: int64还是format: double-int0.54.0seal-object-schemasboolean默认false为对象 schema 默认封口3.0 设additionalProperties: false3.1 设unevaluatedProperties: false0.66.0omit-unreachable-typesboolean默认false开启后仅发射操作引用的类型否则发射服务命名空间下全部类型include-x-typespec-nameinline-only/never默认never是否输出调试用x-typespec-name扩展0.46.0 起默认省略new-linecrlf/lf默认lf输出文件换行符0.14.0experimental-parameter-examplesdata/serialized参数示例的发射方式实验特性1.1.0emitter-output-dir绝对路径输出目录默认{output-dir}/typespec/openapi30.38.0 起替代旧的output-dir另外 0.67.0 起支持编译器的dryRun发射器能力只运行不写盘用于验证与工具链集成0.66.0 起headers的explode选项被正确尊重并使用值语法。若希望把发射结果以对象形式直接交给其他工具处理而不落盘0.54.0 提供的getOpenAPI3函数可直接返回内存中的 OpenAPI 对象。三、文档元数据与装饰器3.1tagMetadata标签元数据0.62.0 引入用于控制 OpenAPI 文档中 tag 的声明与描述。1.13.0 新增summary与kind字段——OpenAPI 3.2 下作为原生 tag 字段输出3.0/3.1 下输出为x-oai-summary/x-oai-kind扩展转换器也能反向读回。1.10.0 增加parent字段支持 3.2 嵌套标签。1.13.0 还支持数组形式显式控制标签声明顺序service tagMetadata(#[ #{ name: First Tag, description: First tag description }, #{ name: Second Tag, description: Second tag description }, ]) namespace PetStore {}注意在同一命名空间上同时混用tagMetadata(#[...])与tagMetadata(name, #{...})属于诊断错误1.9.0 曾修复标签元数据作用域未限定到所声明服务的问题。3.2info与 License 标识0.47.0 起info装饰器可指定 OpenAPI info 对象的附加字段0.54.0 扩展为支持 info 对象的全部属性。1.15.0 进一步为typespec/openapi的License模型新增identifier字段SPDX 许可证表达式如MIT、Apache-2.0且identifier与url互斥OpenAPI 3.1 原样输出3.0 输出为x-oai-license-identifier扩展导入 OpenAPI 时也支持读回该字段。info(#{ license: #{ name: MIT, identifier: MIT }, }) namespace MyService;3.3oneOf与useRefTypeSpec.OpenAPI.oneOf作用于Union | ModelProperty强制该联合用oneOf而非anyOf输出0.8.0 增加校验0.49.0 起允许用于模型属性TypeSpec.OpenAPI.useRef(ref: valueof string)作用于Model | ModelProperty指定外部引用如../../common.json#/components/schemas/Foo替代内联输出0.59.0 起响应也支持useRef。3.4 其他文档装饰器summary/doc0.8.0 起summary与doc分离summary在数据类型上发射为 JSON Schematitle0.50.0doc作用于服务命名空间时设置 OpenAPI 描述0.9.0externalDocs0.9.0 支持1.7.0 修复属性上的externalDocs被忽略extension可施加于服务命名空间0.59.0 起在文档根输出、Security schemes0.58.0、Server 变量0.15.01.14.0 修复其被同时输出到参数对象与 schema 上的重复问题encodedName0.52.0 支持1.13.0 前存在 required 数组未使用encodedName值的问题0.53.2 修复。四、安全认证模型认证方案通过useAuth配置。1.15.0 为OpenIdConnectAuth增加作用域scope支持模型现在接受可选的模板参数OpenIdConnectAuthConnectUrl, Scopes发射器会把 scopes 输出到每个操作的openIdConnect安全要求中scheme 对象本身不变scopes 仍通过openIdConnectUrl发现既有OpenIdConnectAuthUrl用法不受影响。0.53.0 起已支持 OpenIdConnect 认证方案本身0.15.0 曾跟进 http 服务的 oauth2 scopes。相关修复还包括 0.60.0 修复useAuth({})导致的发射器崩溃1.13.0 修复自定义认证方案模型泄漏进components.schemas的问题现在只输出到components.securitySchemes。五、模型语义可见性、判别联合与共享路由可见性visibility0.16.0 实现自动可见性转换按生命周期Read/Create/Update/Delete对模型做视图切分并产生Read/Create后缀的 schema0.42.0 起避免产生Read后缀0.14.0 起避免多余的「canonical」模型。discriminated联合0.66.0 引入0.62.0 起判别属性无论是否可选都标记为 required符合 OpenAPI 规范1.8.0 支持 3.2.0 的defaultMapping默认变体进oneOf数组并通过discriminator.defaultMapping引用3.0/3.1 则加入discriminator.mapping。1.12.0 修复首个变体引起循环发射时缺失 mapping 条目的问题。共享路由shared routes0.43.0 支持1.6.0 起为具有多个不兼容 content-type如 multipart/form-data 与 application/json的操作生成带sharedRoute的独立操作0.66.0 起共享操作可在operationId一致时统一设置 operationId。响应与状态码0.49.0 支持 http 状态码范围0.65.0 起响应生成内联表达式并精简默认值字段同时支持 OpenAPI headers 与 responses 的$ref0.64.0 修复响应体为void但模型含其他字段如statusCode时的编译失败。body/bodyRoot0.56.0 引入区分0.59.0 修复body/bodyRoot下操作示例产生空对象的问题。multipart0.51.0 起bytes部件正确处理为type: string, format: binary1.11.0 修复 multipart 中命名联合含bytes变体时的「Duplicate type name」错误1.4.0 起 http parts 扩展正确输出。六、参数与编码处理cookie0.62.0 引入 cookie 参数装饰器1.14.0 修复导入时 cookie 参数含 nullable 与类型-null schema 变体未生成cookie。集合格式collection formats0.47.0 支持 simple、form、ssv、pipes0.49.0 修复 header 使用 ssv/pipes 时产生非法 schema改为 string 类型并告警1.7.0 为ArrayEncoding枚举新增commaDelimited与newlineDelimited1.14.0 修复encode(ArrayEncoding.commaDelimited)数组被编码为标量时残留items。encode数组编码0.67.0 起encode可为query参数指定数组编码1.15.0 的转换器会把spaceDelimited/pipeDelimited风格的查询参数转为encode(ArrayEncoding.spaceDelimited)/encode(ArrayEncoding.pipeDelimited)包括explode: true时。约束传播1.13.0 修复JsonSchema.uniqueItems未应用到 query/path/header 参数 schema 的问题0.47.0 修复minItems/maxItems未应用到模型数组。默认值0.57.0 起支持对象与数组默认值如decimals: decimal[] #[123, 456.7]0.53.1 起允许联合属性类型的默认值。七、tsp-openapi3OpenAPI → TypeSpec 反向转换器0.58.0 引入tsp-openapi3CLI包含在typespec/openapi3包内此后一直是重点打磨对象。其实现位于 packages/openapi3/src/cliconvert动作下按生成器/转换器/工具分目录组织。7.1 基础导入能力1.4.0 集中落地OASconst常量导入转换时显式指定目标命名空间名discriminator mappings 导入multipart 请求体导入servers 导入tags 元数据导入。7.2 可见性与生命周期1.10.0导入readOnly/writeOnly属性readOnly: true→visibility(Lifecycle.Read)writeOnly: true→visibility(Lifecycle.Create)两者互斥同时出现时发出警告并都忽略。7.3 分页扩展导入1.9.0基于x-ms-*扩展族导入分页装饰器x-ms-list-continuation-token→continuationTokenx-ms-list-*-link→prevLink/nextLink/firstLink/lastLinkx-ms-list→listx-ms-list-offset→offsetx-ms-list-page-size→pageSizex-ms-list-page-items→pageItemsx-ms-list-page-index→pageIndex。7.4 版本化类型编码1.6.01.7.0OpenAPI 的unixtime格式 →utcDateTimeencode装饰器0.59.0 起1.7.0 修复anyOf/oneOf含 unixtime 格式时对 nullableutcDateTime正确发射encode(DateTimeKnownEncoding.unixTimestamp, integer)1.7.0 修复 OpenAPI 3.1/3.2 中contentEncoding: base64→bytes类型 encode(base64, string)1.9.0 将带 duration 格式的数字类型转换为 TypeSpec duration 类型 encode(seconds, float32)。7.5 其他导入修复要点$ref兄弟关键字1.10.0 支持 JSON Schema 2020-12 中$ref旁的兄弟关键字default、约束、deprecated 等0.65.0 支持 requestBodies 中的$refanyOf/oneOf处理1.11.0 修复anyOf中$ref与内联对象被误导入为 model 而非 union1.5.0 拆解单一anyOf/oneOf以还原语义类型0.60.0 改进 enum/unions/scalars/aliases 的处理nullable0.62.0 修复 nullable enum 使用allOf而非oneOf1.10.0 修复anyOfnull的可空数组忽略minItems/maxItems的问题allOf内联1.1.0 支持内联allOfschema0.60.0 使模型正确 extend 唯一带判别器的allOf成员其他成员按 schema 引用或内联展开doc 与转义0.58.0 起自动换行仅保留原文换行1.8.0 修复扩展字符串属性值中的${...}插值转义并避免 JSON 风格字符串触发三引号语法问题1.15.0 起使用spaceDelimited/pipeDelimited的查询参数不再被丢弃SSE 与 XML1.6.0 支持 SSE 事件发射与导入1.8.0 修复 SSE 事件缺失 import 与标识符转义0.62.0 起通过typespec/xml库支持 XML 载荷1.0.0-rc.1 修复 XML 载荷与自定义标量组合的多种问题弃用标记1.8.0 支持导入 deprecated 属性与类型1.13.0 修复deprecated: true导入生成#deprecated deprecated指令operationId1.4.0 起缺失 operationId 时记录警告并生成操作名。八、$ref输出策略的版本差异1.14.0发射端一个重要变化发射 OpenAPI 3.1及 3.2时不再把$ref包进多余的allOf。当被引用 schema 携带兄弟关键字如description、default、readOnly、externalDocs时这些关键字现在直接放在$ref旁——这是 JSON Schema 2020-12 允许的写法OpenAPI 3.0 输出保持不变3.0 不允许$ref兄弟关键字。0.53.0 曾修复 nullable 属性成环时被不必要地包进allOf0.62.0 修复 nullable 存在时 type 属性始终设置这些修复共同保证了$ref输出的稳定性。九、从 CHANGELOG 到源码的验证路径如果你想在仓库里亲自验证上述能力建议按以下路径阅读选项定义与默认值packages/openapi3/src/lib.ts 中OpenAPI3EmitterOptions类型第 8 行起与EmitterOptionsSchema第 144 行起所有选项的取值枚举、默认值与描述一目了然发射主流程packages/openapi3/src/openapi.ts其中resolveOutputFile第 630 行起演示了output-file插值与路径净化getOpenApiFromService等函数负责从 http 服务模型组装 OpenAPI 文档操作 ID 生成packages/openapi3/src/operation-id-resolver/operation-id-resolver.ts 及其同名测试文件对应operation-id-strategy三种策略版本化 schema 发射src/schema-emitter-3-0.ts、schema-emitter-3-1.ts、schema-emitter-3-2.ts三兄弟可对照enum-strategy: annotated、$ref兄弟关键字等 3.1 专属行为转换器src/cli/actions/convert/下按generators生成 TypeSpec 代码、transformsOpenAPI → 中间模型、utils命名、文档、operationId 生成等分层组织是理解 OpenAPI 导入逻辑的入口。十、结语从 0.2.0 的单一 OpenAPI 3.0 输出到今天同时支持 3.0/3.1/3.2 多版本发射、enum-strategy: annotated高保真枚举、operation-id-strategy可定制操作 ID、作用域化的 OpenIdConnect 认证以及能力完整的tsp-openapi3反向转换器typespec/openapi3已经成为 TypeSpec 生态中连接「规范定义」与「OpenAPI 产物」的双向枢纽。在实际项目里建议根据目标消费方Azure 生态工具链、通用代码生成器、还是 3.1 语义敏感的 JSON Schema 工具选择openapi-versions并用enum-strategy、operation-id-strategy、seal-object-schemas三个选项做输出形态的精细化控制——它们正是 CHANGELOG 中投入迭代最多的三个能力面。【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespec创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考