APIが42(数値)ではなく"42"(文字列)を返して、下流の処理がすべて壊れたことはありませんか?あるいは必須フィールドが欠けたリクエストが送られてきて、親切なエラーを返す代わりにアプリがクラッシュしたことは?JSON Schemaはまさにこのような問題を防ぐために存在します。
JSON Schemaは、JSONデータの設計図のようなものです — データがどのような形であるべきかを記述し、一致しないものをキャッチします。
JSON Schemaの見た目
JSON Schema自体がJSONで書かれています(メタですよね?)。ユーザーオブジェクトのシンプルなスキーマの例を見てみましょう:
これは「必須のname(空でない文字列)とemail(有効なメール形式)、そしてオプションのage(0から150の整数)を持つオブジェクトを期待する」という意味です。もし誰かが{"name": "", "email": "not-an-email"}を送信したら、バリデーターは両方の問題を検出します。
スキーマを段階的に構築する
型から始める。 すべてのスキーマは"type"で始まります:object、array、string、number、integer、boolean、null。
制約を追加する。 文字列にはminLength、maxLength、pattern(正規表現)。数値にはminimum、maximum、multipleOf。配列にはminItems、maxItems、uniqueItems。公式JSON Schemaガイドに完全なリストがあります。
必須フィールドをマークする。 オブジェクトレベルで"required"配列を使います。本当に存在しなければならないフィールドだけをリストしましょう — 本気でない限り、すべてを必須にしないでください。
ネストされたオブジェクトを定義する。 "properties"の中にスキーマ定義をネストするだけです。アドレス付きのユーザーの例:
郵便番号のpatternは?5桁の米国郵便番号のみを受け入れるようにしています。このような実用的なバリデーションは、ゴミデータがデータベースに紛れ込むのを防ぎます。
なぜ実際に使うべきか
APIバリデーション: APIの入り口で受信リクエストボディを検証しましょう。不正なデータはビジネスロジックに触れる前に、明確なエラーメッセージで拒否されます。ほとんどのフレームワークがこれをサポートしています — JavaScriptのAjvは非常に高速です。
設定ファイルの検証: アプリ起動時に設定ファイルを検証しましょう。5分後の不明瞭なnullポインタ例外ではなく、「設定にdatabase.hostフィールドがありません」という明確なメッセージで早期に失敗させましょう。
ドキュメント: JSON Schemaは生きたドキュメントとしても機能します。Swagger UIなどのツールがスキーマから直接APIドキュメントを生成します。
コード生成: スキーマからTypeScriptインターフェース、Go構造体、Pythonデータクラスを生成できます。一度書けば、どこでも使えます。
テスト: テストスイートでAPIレスポンスを検証し、リグレッションを自動的に検出します。
30秒で始める
最も速い方法は?既存のJSONデータからスキーマを生成することです。サンプルのJSONレスポンスを当サイトのJSON Schema Generatorに貼り付けてください — データを分析して、あなたが洗練できるスキーマを生成します。そしてJSON Schema Validatorを使って実際のデータに対してテストしましょう。
プログラムで検証することもできます。Ajvを使ったNode.jsの簡単な例:
Pythonではjsonschemaライブラリをチェックしてください。Javaにはeverit-json-schemaがあります。ほぼすべての言語にしっかりしたサポートがあります — 実装の完全なリストをご覧ください。
知っておくべき高度なスキーマ機能
基本をマスターしたら、JSON Schemaには複雑なバリデーションを可能にする強力な機能があります。
oneOf、anyOf、allOf — スキーマの組み合わせ:
フィールドが複数の型のいずれかになることがあります。例えば、APIが文字列IDまたは数値IDのどちらも受け入れる場合:
このスキーマは{"id": "PRD-1234"}と{"id": 42}の両方を受け入れますが、{"id": -1}や{"id": "invalid"}は拒否します。
$ref — 再利用可能なスキーマ定義:
スキーマが大きくなると、同じ定義の繰り返しを避けたくなります。$refキーワードを使えば、共有定義を参照できます:
これでbilling_addressとshipping_addressの両方がまったく同じバリデーションルールを使います。addressの定義を一度変更すれば、両方のフィールドが更新されます。大きなスキーマを保守可能に保つために不可欠です。
additionalProperties — オブジェクトをロックダウン:
デフォルトでは、JSON Schemaはpropertiesに記載されていない追加プロパティを許可します。これは多くの場合、望ましくありません — 予期しないフィールドはクライアントのバグやバージョンの不一致を示す可能性があります。"additionalProperties": falseを設定して、未知のフィールドを拒否しましょう:
このスキーマでは、{"name": "Alice", "email": "[email protected]", "admin": true}はadminが定義されたプロパティではないため拒否されます。
よくあるJSON Schemaの間違い
経験豊富な開発者でもスキーマを書くときにこれらの間違いを犯します:
1. requiredがプロパティレベルではなくオブジェクトレベルであることを忘れる。 これは間違いです:
正しい方法はこちら:
2. "type": "integer"を意味するのに"type": "number"を使う。 number型は3.14のような小数を受け入れますが、integerは整数のみを受け入れます。フィールドがカウントやIDの場合はintegerを使いましょう。
3. 一般的なパターンにformatを指定しない。 JSON Schemaにはemail、uri、date-time、ipv4、ipv6、uuidなどのビルトインフォーマットバリデーターがあります。複雑な正規表現パターンを書く代わりにこれらを使いましょう。
4. すべてを必須にする。 本当に存在しなければならないフィールドだけを必須にしましょう。スキーマを過度に制約すると、APIの進化が難しくなります — 新しいオプションフィールドの追加は非破壊的変更ですが、すべてが必須だとその柔軟性を失います。
実践例:Eコマース商品スキーマ
商品APIで使える実用的なスキーマを見てみましょう:
このスキーマは、すべての商品に名前(1-200文字)、正の価格、固定リストからのカテゴリがあることを保証します。タグはオプションですが、最大10個のユニークな文字列でなければなりません。enumキーワードは特定の値のみを受け入れるべきフィールドに非常に便利です。
JSON Schemaのバージョン:どのDraftを使うべきか
JSON Schemaにはいくつかのドラフトがあり、それぞれIETF Internet-Draftとして公開されています。初心者には混乱するかもしれません。簡単な概要:
| Draft | 年 | ステータス | 主な機能 |
| Draft 4 | 2013 | レガシー | 最も広くサポート |
| Draft 6 | 2017 | レガシー | const、contains追加 |
| Draft 7 | 2018 | レガシー | if/then/else追加 |
| 2019-09 | 2019 | 安定版 | definitionsを$defsに改名 |
| 2020-12 | 2020 | 最新版 | タプル用のprefixItems追加 |
新しいプロジェクトには2020-12(最新版)を使いましょう。既存のコードベースで作業している場合は、バリデーターがどのドラフトをサポートしているか確認してください。Ajvのような最新のバリデーターのほとんどはDraft 7以降をサポートしています。
JSON Schemaをワークフローに統合する
Express.js APIにJSON Schemaバリデーションを追加する実用的なアプローチ:
このパターンにより、明確なエラーメッセージ付きの自動リクエストバリデーションが得られます。allErrors: trueオプションにより、最初のエラーだけでなく、すべてのバリデーションエラーが一度に報告されます。
自分で試してみよう
プロジェクトにスキーマバリデーションを追加する準備はできましたか?これらのツールから始めましょう:
- JSON Schema Generator — 任意のJSONデータを貼り付けて、自動的にスキーマを生成します。サンプルAPIレスポンスからスキーマをブートストラップするのに最適です。
- JSON Schema Validator — 実際のデータに対してスキーマをテストし、検出すべきものを検出し、許可すべきものを許可しているか確認します。
- JSON Validator — スキーマバリデーションの前に、JSONが構文的に正しいかすばやく確認します。
JSON Schemaは最初は余分な作業に見えるかもしれませんが、ビジネスロジックの奥深くではなくシステムの境界でバグをキャッチすることで、何倍にも元が取れます。