[[orval]]を使って、[[OpenAPI Specification]]から[[Zod]]の[[TypeScript]]スキーマコードを自動生成する方法。 ## 前提条件 - [[Bun]] v1.1.6 ## Bunのプロジェクト作成 ```console mkdir orval-sample cd orval-sample bun init . -y ``` ## インストール [[orval]]を[[devDependencies]]としてインストール。[[Zod]]は通常の[[dependencies]]として。 ```console bun add --dev orval bun add zod ``` ## yamlファイル作成 [[Swagger Editor]]の[サンプル](https://editor.swagger.io/)をそのまま拝借する。`spec.yaml`として作成。 ```yaml openapi: 3.0.0 info: title: ReqRes API description: Fake data CRUD API version: "1" servers: - url: https://reqres.in/api components: schemas: User: type: object properties: id: type: integer email: type: string first_name: type: string last_name: type: string avatar: type: string required: ["id"] paths: /users: get: summary: Fetches a user list parameters: - in: query name: page schema: type: integer - in: query name: per_page schema: type: integer responses: '200': description: Success content: application/json: schema: type: object properties: page: type: integer per_page: type: integer total: type: integer total_pages: type: integer data: type: array items: $ref: '#/components/schemas/User' ``` ## 設定ファイルの作成 `orval.config.ts`を作成。 ```ts import { defineConfig } from "orval"; export default defineConfig({ petstore: { output: { client: "zod", mode: "single", target: "./zod", }, input: { target: "./spec.yaml", }, }, }); ``` ## 実行 `zod`ディレクトリを作成。 ```console mkdir zod ``` そして実行。 ```console bun x orval ``` ## 結果確認 `zod/reqResAPI.ts`が作成されている。 ```ts /** * Generated by orval v6.28.2 🍺 * Do not edit manually. * ReqRes API * Fake data CRUD API * OpenAPI spec version: 1 */ import { z as zod } from 'zod' /** * @summary Fetches a user list */ export const getUsersQueryParams = zod.object({ "page": zod.number().optional(), "per_page": zod.number().optional() }) export const getUsersResponse = zod.object({ "page": zod.number().optional(), "per_page": zod.number().optional(), "total": zod.number().optional(), "total_pages": zod.number().optional(), "data": zod.array(zod.object({ "id": zod.number(), "email": zod.string().optional(), "first_name": zod.string().optional(), "last_name": zod.string().optional(), "avatar": zod.string().optional() })).optional() }) ```