解锁API互操作性:将OpenAPI转换为打字稿JSON模式
#javascript #typescript #node #openapi

介绍

这篇文章简要地讲述了我为什么写koude0的故事,以填补 OpenAPI规范之间存在的意外差距 typescript JSON Schema 格式。

序幕

在最近几周的工作中,我面临着一项明显的任务,我认为这有明显的技术解决方案,从我天真的前部工程师背景中:

给定 OpenAPI规范,生成相关的 json schema 要消费并用 typeScriptcript 应用程序来键入的文件。

主要思想包括利用koude1之类的库从生成的JSON模式文件中推论打字稿类型。这是AjvFastify所记录的一种非常普遍的模式,仅举几例:

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模式

主要缺点包括打字稿无法:

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模式周围的$refs的初步尝试之后,我最终将几行组合在一起以自动化我最终将其抽象为JS NPM软件包中的过程:koude0

生成流程包括:

  1. 解决外部/远程$refs,并用koude11(解决$ref的)将它们解释
  2. 使用koude13koude14转换为JSON模式
  3. 为每个定义生成一个打字稿JSON架构文件(带有as const断言的.ts文件)
  4. 将模式存储在反映原始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所采用的方法,并在那里开始讨论,以防万一某些东西不适合您的用例。