Skip to content

Gk0Wk/openapi-thrift

Repository files navigation

@sttot/openapi-render

受限 profile 的 OpenAPI 校验与渲染工具,面向中央 OpenAPI YAML 单向生成 APIFox、CloudWeGo hz / kitex Thrift IDL,以及前端 API client 的工程链路。

CI npm version npm downloads license node GitHub stars

它不是通用 OpenAPI codegen,也不会默默降级 unsupported schema;定位是一个对受限 OpenAPI profile 做显式、可审计、fail-fast 的校验和渲染入口。openapi-thrift CLI 名称仍保留为旧 Hz bootstrap 的别名,新命令面统一叫 openapi-render

为什么用它

  • 只接受已冻结的 OpenAPI Render profile,不做“看起来能转、实际上丢语义”的静默兼容
  • 在 APIFox 渲染、Thrift IDL 投影、前端 API 生成前统一校验同一份 OpenAPI
  • 对 unsupported 能力默认 fail-fast,避免把非法契约带进 APIFox、hz / kitex 或前端 client
  • 纯 TypeScript 实现,同一套逻辑可在浏览器、Node CLI、CI 中复用
  • 当前内置 Thrift IDL 输出,便于继续接 hz updatekitex、模板化生成链路

安装

npm install @sttot/openapi-render

或:

pnpm add @sttot/openapi-render

目标

  • 只支持 ISpark 短剧大师 已冻结的 OpenAPI profile
  • 不做“万能转换器”
  • 核心逻辑保持纯 TypeScript,便于浏览器和 CLI 复用
  • 第一版内置 APIFox/HZ-Thrift profile 校验和 .thrift 文本输出,不直接调用 hzkitex、APIFox 或前端生成器

OpenAPI Render profile

validate 子命令执行 apifox-hz-thrift profile,当前覆盖:

  • APIFox 作者侧规则:requestBody.examples / schema.example(s) / parameter example 的类型一致性,字段级 x-apifox-mock 非空表达式,mockScript 非空且提示人工复核,JSON request body 必须使用 application/json 而不是 APIFox 导出风险较高的 json 简写。
  • 数据模型引用规则:schema $ref 只允许 #/components/schemas/*,requestBody $ref 只允许 #/components/requestBodies/*,response $ref 只允许 #/components/responses/*,parameter $ref 会被判定为 Hz/Thrift 不可投影。
  • Auth 规则:securitySchemes 只能使用标准 apiKey/http/oauth2/openIdConnect,operation/root security 必须引用已声明 scheme;公开接口使用 security: []
  • Hz/Thrift 可表达范围:复用下方 “当前支持 / 当前不支持” 的受限投影规则,并在校验阶段额外执行一次真实 Thrift 投影探针。

当前支持

  • OpenAPI 3.0 JSON
  • operationId;若缺失,可通过 --idl-dir 从既有 Thrift 路由索引回填方法名
  • application/json 主 request/response body,以及 APIFox 导出的 json content-type 别名
  • 单一非 JSON success response:投影为带 api.raw_body="" 的响应包装结构
  • application/x-www-form-urlencoded 请求体 -> api.form
  • multipart/form-data 的普通字段 -> api.form
  • path/query/header/cookie 参数
  • 单一 204 / 空 success response -> EmptyResponse
  • query array 参数的默认 form + explode=true(重复 key)序列化
  • object / array / scalar / 有限 map<string, T>
  • 顶层 scalar requestBody 会退化为单字段 api.raw_body="" 请求结构
  • 组件 schema 本地引用:#/components/schemas/*
  • 组件 requestBody 本地引用:#/components/requestBodies/*
  • required / default / enumgo.tag validate/default 的有限投影
  • minimum/maximum -> gte/lte
  • minLength/maxLength -> min/max
  • minItems/maxItems -> min/max
  • 白名单 format -> validate tag:base64 / date / date-time / email / e164 / hexcolor / hostname / ipv4 / ipv6 / json / jwt / uri / url / ulid / uuid / uuid3 / uuid4 / uuid5
  • 标准标量格式:
    • integer: int32 / int64
    • number: float / double
    • string: binary
  • nullable union:anyOf [T, null]
  • 可组合对象 allOf 的最小支持(当前已覆盖 JobSeek 出现的单 ref 包装)
  • 可通过 vendor extension 显式接管少量不支持的字段校验:
    • x-dramawork-allow-unsupported-validation: true
    • x-dramawork-validate: "custom_rule"string[]

当前不支持

  • oneOf
  • 非 nullable 的 anyOf
  • 复杂 allOf 继承拼装
  • pattern(当前会显式报错;如确有统一 validator,可用 x-dramawork-validate 显式接管)
  • multipleOf(当前会显式报错;如确有统一 validator,可用 x-dramawork-validate 显式接管)
  • additionalProperties: false(当前会显式报错;这属于 binder/decoder 级约束,不能通过字段 validator 接管)
  • 未列入白名单的 string format(当前会显式报错,要求手写 validator 或收紧 schema)
  • GET/DELETE/HEAD/OPTIONS requestBody
  • multipart/form-data 文件字段(单文件和多文件当前都会显式报错;APIFox 可导出 string/binary,但 Hertz 官方文档说明 IDL 场景不支持文件绑定)
  • object query 参数
  • deepObject query
  • spaceDelimited / pipeDelimited query
  • 非默认 form + explode=true 的 query array 序列化
  • parameter.content
  • parameter $ref
  • 多个 2xx success response
  • 并行多 content-type(当前 APIFox 导入/导出工作流也会把它收敛为单一 application/json
  • oneOf + discriminator
  • 非 JSON success response 对应的 object/array schema
  • additionalProperties: true
  • 包含空白字符的 string enum

手写校验逃生口

当某个字段使用了当前不支持自动投影的规则,但你已经在 Hertz/validator 侧准备好了手写校验器,可以显式写:

{
  "type": "string",
  "pattern": "^1\\d{10}$",
  "x-dramawork-allow-unsupported-validation": true,
  "x-dramawork-validate": "cn_mobile"
}

或者:

{
  "type": "number",
  "multipleOf": 0.5,
  "x-dramawork-allow-unsupported-validation": true,
  "x-dramawork-validate": ["half_step", "gte=0"]
}

这条能力的含义是“我明确知道这里不是自动生成,而是人工接管”。如果只写允许开关、不提供 x-dramawork-validate,converter 会直接报错。

注意:

  • 这条逃生口只适用于“字段 validator 能感知到的约束”,例如 patternmultipleOf、部分未白名单 format
  • additionalProperties: false 不属于这一类;JSON 绑定完成后,多余字段通常已经被丢弃,单靠字段 validator 无法恢复这条语义

APIFox 边界矩阵

当前 APIFox 真实导出、converter 支持面和 profile 结论见:

当前还额外固化了两份 APIFox 真实导出 followup fixture:

  • apifox-boundary-lab.followup.export.openapi.json
    • 确认 204 / 空 success response 会稳定保留
    • 确认并行多 content-type 在当前 APIFox 导入/导出工作流里会被收敛成单一 application/json
  • apifox-boundary-lab.header-cookie.export.openapi.json
    • 确认 header / cookie 参数会稳定保留为标准 parameter
    • 确认 header 名大小写按导出结果原样保留,例如 X-Request-ID

使用方式

仓内开发先构建:

pnpm --dir standard/openapi-thrift build

如果从 npm 安装,建议直接用 npx

npx @sttot/openapi-render validate --input ./project.openapi.json
npx @sttot/openapi-render thrift --input ./project.openapi.json --output ./idl/project.thrift

再运行 CLI:

node standard/openapi-thrift/dist/cli.js \
  validate \
  --input ./project.openapi.json

生成 Thrift:

node standard/openapi-thrift/dist/cli.js \
  thrift \
  --input ./project.openapi.json \
  --namespace dramawork.project \
  --service-name ProjectService

带既有 IDL 路由索引一起运行:

node standard/openapi-thrift/dist/cli.js \
  thrift \
  --input ./project.openapi.json \
  --idl-dir D:/Developer/JobSeek/tutoring-demand/idl \
  --output ./idl/project.thrift

输出到文件:

node standard/openapi-thrift/dist/cli.js \
  thrift \
  --input ./project.openapi.json \
  --output ./idl/project.thrift

以库方式调用:

import {
  assertOpenApiRenderDocument,
  convertOpenApiToThrift,
} from "@sttot/openapi-render"

assertOpenApiRenderDocument(openApiDocument)

const result = convertOpenApiToThrift(openApiDocument, {
  namespace: "dramawork.project",
  serviceName: "ProjectService",
})

console.log(result.thrift)

开发命令

pnpm --dir standard/openapi-thrift typecheck
pnpm --dir standard/openapi-thrift lint
pnpm --dir standard/openapi-thrift build
pnpm --dir standard/openapi-thrift test

About

Restricted OpenAPI 3.0 JSON -> Thrift IDL projector for APIFox and CloudWeGo workflows.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors