JSON → JSON Schema

JSONを貼り付けるだけでJSON Schema draft-07を即座に生成。型・必須フィールド・ネスト構造を自動推論。無料・ブラウザ内で処理・登録不要。

  • ブラウザ内で処理
  • データはブラウザ外に出ません
  • 無料 · 登録不要
入力、生成したスキーマ、エラーメッセージを消去します。ツール内の Ctrl/⌘+L でも消去し、JSON 入力にフォーカスを戻します。
サンプル JSON を編集するか自分のデータを入力します。入力の変更ごとに draft-07 JSON Schema を即座に生成します。配列は全要素をマージし、すべてのサンプルオブジェクトに null 以外の値であるキーを必須にします。
JSON Schema (draft-07)
生成したスキーマ全文をコピーします。出力は読み取り専用です。エディターに貼り付けて制約や必須フィールドを調整してください。空の出力はコピーしません。

JSON を入力すると draft-07 スキーマを生成します。

例・詳しい説明・よくある質問 実際の出力つきの例、ほかのツールとの違い、よくある質問。

JSON Schema とは

JSON Schema は、JSON データの構造を JSON で書き表すための仕様です。各フィールドの型、必須かどうか、ネストしたオブジェクトの形を定義し、Ajv などのバリデーターがそれに沿ってデータを検査します。API の入力チェック、コード生成、ドキュメント作成に使われます。このツールはサンプルの JSON から draft-07 のスキーマを推論し、ゼロから手書きする手間を省きます。

出力の見方

生成されたスキーマには常にdraft-07を指す $schema が含まれます。 オブジェクトのプロパティはJSONのキーから推論され、 required 配列にはnull以外のすべてのキーが列挙されます。 配列の items は実際の要素から型を推論します。

生成後の改善ポイント

生成されたスキーマはあくまでも出発点です。よくある改善として、 フィールドへの description 追加、 minLength や pattern による文字列制約の強化、 オプションフィールドの required からの除外、 既知の値セットへの enum 追加などがあります。

変換例

入力:

{
  "orderId": 1001,
  "total": 59.9,
  "coupon": null,
  "items": [{ "sku": "A1", "qty": 2 }],
  "tags": []
}

出力:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "orderId": { "type": "integer" },
    "total": { "type": "number" },
    "coupon": { "type": "null" },
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "sku": { "type": "string" },
          "qty": { "type": "integer" }
        },
        "required": ["sku", "qty"]
      }
    },
    "tags": { "type": "array", "items": {} }
  },
  "required": ["orderId", "total", "items", "tags"]
}
  • 整数は integer、小数は number になります。qty が 1.5 になりうるなら number に変えます。
  • サンプルの coupon は null なので、型は null で required にも入りません。文字列も入るなら型を ["string", "null"] にします。
  • 空の配列は "items": {} になり、どんな要素も通ります。

郵便番号検索 API のレスポンスから作る

zipcloud の郵便番号検索API は、成功すると results に住所の配列を、エラーのときは results に null、message にエラー内容を入れて返します。ドキュメントのレスポンスサンプル(2 件のうち 1 件)から作ると次のようになります。

{
  "message": null,
  "results": [
    {
      "address1": "北海道", "address2": "美唄市", "address3": "上美唄町協和",
      "kana1": "ホッカイドウ", "kana2": "ビバイシ", "kana3": "カミビバイチョウキョウワ",
      "prefcode": "1", "zipcode": "0790177"
    }
  ],
  "status": 200
}

生成されるスキーマ:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "message": { "type": "null" },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "address1": { "type": "string" }, "address2": { "type": "string" }, "address3": { "type": "string" },
          "kana1": { "type": "string" }, "kana2": { "type": "string" }, "kana3": { "type": "string" },
          "prefcode": { "type": "string" }, "zipcode": { "type": "string" }
        },
        "required": ["address1", "address2", "address3", "kana1", "kana2", "kana3", "prefcode", "zipcode"]
      }
    },
    "status": { "type": "integer" }
  },
  "required": ["results", "status"]
}

このスキーマでドキュメントのエラー時サンプル("message": "必須パラメータが指定されていません。"、"results": null、"status": 400)を検査すると、message が文字列、results が null なので通りません。成功時だけのサンプルでは、エラー時の形が分からないからです。成功時とエラー時のレスポンスを配列にまとめて生成すると、要素のスキーマが両方を受け入れる形になります。

[
  { "message": null, "results": [{ "zipcode": "0790177", "address1": "北海道" }], "status": 200 },
  { "message": "必須パラメータが指定されていません。", "results": null, "status": 400 }
]
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "message": { "type": ["null", "string"] },
      "results": {
        "type": ["array", "null"],
        "items": {
          "type": "object",
          "properties": { "zipcode": { "type": "string" }, "address1": { "type": "string" } },
          "required": ["zipcode", "address1"]
        }
      },
      "status": { "type": "integer" }
    },
    "required": ["status"]
  }
}
  • 1 件のレスポンスを検査するには items の中身を使います。両方のレスポンスにある status だけが必須になります。
  • zipcode は JSON で "0790177" と文字列として書かれているので string になります(数値の 790177 なら integer)。桁数までは検査しないので、必要なら "pattern": "^[0-9]{7}$" を自分で追加します。
  • カナ(kana1 など)は半角カナですが、型は string で文字の種類は区別しません。

Ajv で検証する

Ajv 8 は既定の Ajv クラスで draft-07 を検証できます。format キーワードには ajv-formats が必要で、入れないと compile() が unknown format "email" を投げます。

import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv();
addFormats(ajv);

const validate = ajv.compile({
  type: 'object',
  properties: {
    email: { type: 'string', format: 'email' },
    coupon: { type: ['string', 'null'] },
  },
  required: ['email'],
  additionalProperties: false,
});

validate({ email: 'a@example.com', extra: 1 }); // false: must NOT have additional properties

ジェネレーターは format、minimum、maxLength、pattern、enum、additionalProperties: false を付けません。データが守るべきルールに合わせて追加してください。

制限事項

  • 配列の要素はマージします。 [{"id": 1, "name": "Alice"}, {"id": 2, "email": "b@example.com"}] では items に id・name・email が入り、必須はすべての要素にある id だけです。同じ配列の整数と小数は "number" になります。生成したスキーマは元のサンプルを必ず通します。GenSON も同じ方法でサンプルをマージします。
  • 必須はサンプルから決まります。 1 つのオブジェクトでは null 以外のキーがすべて required に入ります。データでは任意でもサンプルにあるフィールドは、自分で required から外します。
  • 型が混ざると型のリストになります。 [1, "x", {"a": 1}] は "type": ["integer", "string", "object"] になり、横にオブジェクトの properties と required が付きます。この 2 つはオブジェクトの要素にだけ適用されます。
  • draft-07 のみ。 2020-12 を使うなら $schema を変え、Ajv の Ajv2020 クラスを使います。

FAQ

このツールはどのバージョンのJSON Schemaを生成しますか?

広くサポートされているJSON Schema draft-07を生成します。AJV・jsonschema(Python)などの主要バリデーターと互換性があり、ZeroToolのJSON Schemaバリデーターでもそのまま使えます。

必須フィールドはどのように決まりますか?

入力JSONオブジェクト内のnull以外のすべてのプロパティがrequired配列に追加されます。null は値があるとは限らないため除外されます。オブジェクトの配列では、すべてのオブジェクトに null 以外の値で存在するキーだけが必須になります。出力スキーマを編集してrequiredリストを調整できます。

ネストしたオブジェクトや配列に対応していますか?

対応しています。ネストしたオブジェクトと配列を再帰的に処理します。配列の items スキーマはすべての要素をマージして作り、どの要素も通ります。ネストオブジェクトはpropertiesとrequired配列を生成します。

生成したスキーマをバリデーションに使えますか?

使えます。生成したスキーマをZeroToolのJSON Schemaバリデーターやその他のAJVベースバリデーターに貼り付けてください。オプションフィールドの調整やminLength・minimum・patternなどの追加制約が必要な場合があります。

JSON はサーバーに送信されますか?

いいえ。スキーマは入力に合わせてブラウザーのタブの中で生成し、入力した JSON をサーバーへ送ったり、ブラウザーのストレージに保存したりしません。入力欄の編集を終えたときとスキーマをコピーしたときに、ページのアクセス解析が利用イベント(ツール名と convert または copy という操作名)を 1 件記録するだけで、JSON やスキーマの内容は含みません。

半角カナや全角数字の値はどう扱われますか?

どちらも文字列なので "type": "string" になるだけで、文字の種類は検査しません。zipcloud の kana1 のように半角カナだけを許したい場合は、"pattern": "^[ヲ-゚]+$" のような制約を自分で追加します。このパターンは ホッカイドウ を通し、全角の ホッカイドウ を拒否します。