介绍
这篇文章简要地讲述了我为什么写koude0的故事,以填补 OpenAPI规范之间存在的意外差距和 typescript JSON Schema 格式。
。序幕
在最近几周的工作中,我面临着一项明显的任务,我认为这有明显的技术解决方案,从我天真的前部工程师背景中:
给定 OpenAPI规范,生成相关的 json schema 要消费并用 typeScriptcript 应用程序来键入的文件。
主要思想包括利用koude1之类的库从生成的JSON模式文件中推论打字稿类型。这是Ajv和Fastify所记录的一种非常普遍的模式,仅举几例:
import { FromSchema } from "json-schema-to-ts";
// This schema should be generated from OpenAPI specification
const dogSchema = {
type: "object",
properties: {
name: { type: "string" },
favoriteFood: { enum: ["pizza", "taco", "fries"] },
},
required: ["name", "favoriteFood"],
} as const;
type Dog = FromSchema<typeof dogSchema>;
// => Will infer the same type as above
由于OpenAPI Specification是“机器可读接口定义语言,要描述[...] Web Services” ,而TypeScript实际上是Node.js的唯一可用类型解决方案,我自信谷歌搜索:
“ openapi to typeScript json架构”
...也没有发现相关结果。
OpenAPI到打字稿JSON模式差距
如果 OpenAPI->打字稿类型主要由koude2和 OpenApi-> JSON Schema koude3涵盖,没有明确的方法来生成Typescript openapi定义的JSON模式。
主要缺点包括打字稿无法:
- 解释/解决JSON Schema的
$ref
和$id
Props - 导入json文件
as const
(请参阅relevant GitHub thread)
const dogSchema = {
type: "object",
properties: {
name: { type: "string" },
// TS cannot interpret/resolve $refs
favoriteFood: { "$ref": "components/schemas/Food" },
},
required: ["name", "favoriteFood"],
} as const;
考虑上面的示例,为了拥有一个json模式,打字稿可以正确解释哪个typecript,所有$ref
条目都应以某种方式静态解决。
在最初尝试替换JSON模式周围的$ref
s的初步尝试之后,我最终将几行组合在一起以自动化我最终将其抽象为JS NPM软件包中的过程:koude0。
生成流程包括:
- 解决外部/远程
$ref
s,并用koude11(解决$ref
的)将它们解释 - 使用koude13和koude14转换为JSON模式
- 为每个定义生成一个打字稿JSON架构文件(带有
as const
断言的.ts
文件) - 将模式存储在反映原始OpenAPI定义结构的文件夹结构中
上面的示例将导致 typescript json schema 文件,准备进口和消费:
import componentsSchemasFood from "./../components/schemas/Food"
export default {
type: "object",
properties: {
name: { type: "string" },
favoriteFood: componentsSchemasFood,
},
required: ["name", "favoriteFood"],
} as const;
由于v0.3.0,$ref
定义被生成为独立ts json架构文件并在需要时导入。
结论
鉴于JSON模式在大部分网络开发中的中心地位,我很高兴看到Typescript接管并通过添加本机支持:
来使JSON Schemas一流公民成为一流的公民。- 导入JSON模式导入const
- 从任何JSON模式(目前使用未杰出的koude1实现)本地推断类型
与此同时,请随时查看koude0所采用的方法,并在那里开始讨论,以防万一某些东西不适合您的用例。