ネストされたJSONオブジェクトをZodスキーマに変換する

ネストされたサブオブジェクトを持つJSONから複数のZodスキーマ定数を生成する方法を学びます。各ネストオブジェクトが再利用可能なスキーマを取得します。

Basic Types

詳細な説明

Zodでのネスト構造の処理

実際のJSONがフラットであることはほとんどありません。APIは通常、オブジェクトの中にオブジェクトを返し、各ネストレベルが個別のZodスキーマ定数にマッピングされ、それらを組み合わせて使用できます。

JSON例

{
  "id": 1,
  "name": "Acme Corp",
  "address": {
    "street": "123 Main St",
    "city": "Springfield",
    "geo": {
      "lat": 39.7817,
      "lng": -89.6501
    }
  }
}

生成されるZodスキーマ

import { z } from "zod";

const geoSchema = z.object({
  lat: z.number(),
  lng: z.number(),
});

const addressSchema = z.object({
  street: z.string(),
  city: z.string(),
  geo: geoSchema,
});

const companySchema = z.object({
  id: z.number().int(),
  name: z.string(),
  address: addressSchema,
});

type Geo = z.infer<typeof geoSchema>;
type Address = z.infer<typeof addressSchema>;
type Company = z.infer<typeof companySchema>;

なぜ個別のスキーマに分けるのか

ネストされたオブジェクトを個別のスキーマに抽出することで、以下の利点があります:

  1. 再利用性geoSchemaは座標が出現する任意の場所(店舗の所在地、イベント会場など)で再利用できます。
  2. 合成可能性 — Zodスキーマは自然に合成されます。既存のスキーマを拡張、マージ、またはフィールドを選択できます。
  3. テスト容易性addressSchemacompanySchemaとは独立してバリデーションでき、ユニットテストがシンプルになります。
  4. 可読性 — 深くネストされたインラインスキーマはすぐに読みにくくなります。

スキーマの合成方法

Zodは強力な合成ツールを提供します:

// スキーマの拡張
const detailedAddressSchema = addressSchema.extend({
  zipCode: z.string(),
});

// 2つのスキーマのマージ
const fullSchema = addressSchema.merge(contactSchema);

// 特定フィールドの選択
const locationSchema = addressSchema.pick({ city: true, geo: true });

これらの合成パターンにより、シンプルでテスト済みのビルディングブロックから複雑なバリデーションを構築できます。

ユースケース

住所や位置情報のサブオブジェクトを含む深くネストされた企業データを返すサードパーティAPIを統合し、すべてのネストレベルでランタイムバリデーションが必要な場合に使用します。

試してみる — JSON to Zod Schema

フルツールを開く