JSONバリデーション完全ガイド:構文・スキーマ・ベストプラクティス
JSONバリデーションは、信頼性の高いAPI、設定パイプライン、データ駆動型アプリケーションを構築する上で最も重要なステップのひとつです。たったひとつの不正なJSONペイロードが、サービスのクラッシュ、気づきにくいデータ破損、あるいはセキュリティ脆弱性を引き起こす可能性があります。このガイドでは、基本的な構文ルールから構造的なスキーマ検証まで、JSONバリデーションのあらゆる側面を解説し、実際のシナリオへの適用方法を示します。
JSONバリデーションが重要な理由
JSONは一見シンプルに見えます。6種類のデータ型と最小限の構文で書きやすい反面、間違いも起こりやすいです。バリデーションはエラーを早期に、データがシステムに入ってくる境界で検出することで、下流に伝播して発見困難なバグになる前に問題を捉えます。
アプリケーションを守る3つのバリデーション層:
- 構文バリデーション — JSONとしてパースできるか?
- 型バリデーション — 値が期待するデータ型か?
- スキーマバリデーション — 構造がアプリケーションの期待する形と一致しているか?
JSONの構文ルール
1. キーはダブルクォートで囲む
すべてのオブジェクトのキーはダブルクォートで囲む必要があります。シングルクォート、クォートなしの識別子、数値キーはすべて無効です。
// 無効{ name: "Alice", 'age': 30 }// 有効{ "name": "Alice", "age": 30 }
2. 末尾のカンマは禁止
オブジェクトや配列の最後の要素の後に末尾カンマを付けることはJSONでは禁止されています。JavaScriptでは許可されていますが、JSONでは認められません。
// 無効{"host": "localhost","port": 5432,}// 有効{"host": "localhost","port": 5432}
3. コメントは使用不可
JSONにはコメント構文がありません。// も /* */ も有効ではありません。
コメント付きの設定ファイルが必要な場合は、JSONCやJSON5(JSONのスーパーセット)の使用を検討してください。ただし、標準のJSONパーサーはこれらを拒否することに注意が必要です。
4. 文字列は適切にエスケープする
文字列内の特殊文字はバックスラッシュでエスケープする必要があります。
{"path": "C:\\Users\\alice\\documents","message": "彼女は \"hello\" と言いました","newline": "1行目\n2行目"}
5. 数値は厳格なルールに従う
JSON数値は先頭にゼロを付けられません(0 自体は除く)。NaN や Infinity も使用できません。また、数値を表す場合はクォートで囲んではいけません。
// 無効{ "value": 0123, "ratio": Infinity }// 有効{ "value": 123, "ratio": 1e308 }
6. トップレベルの値は有効なJSON値であること
JSONドキュメントのルートには、オブジェクト、配列、文字列、数値、真偽値、nullのいずれかを置くことができます。空ファイルや識別子はJSONとして無効です。
よくあるJSONエラーと修正方法
| エラー | 原因 | 修正方法 |
|---|---|---|
| Unexpected token | シングルクォート、末尾カンマ、クォートなしキー | ダブルクォートの文字列に置き換え、末尾カンマを削除 |
| Unexpected end of input | 閉じ括弧や閉じ角括弧の不足 |
|
| Invalid escape sequence | エスケープされていないバックスラッシュ、または無効な | バックスラッシュを |
| Duplicate keys | 同じキーがオブジェクト内に複数存在する | 重複しているキーを削除するか名前を変更する |
| Wrong value type |
| 真偽値とnullリテラルを囲むクォートを削除する |
JSON Schemaによる構造バリデーション
構文バリデーションはJSONがパース可能かどうかを確認するだけです。スキーマバリデーションは「正しい」かどうかを確認します——データがアプリケーションの期待する形に一致しているかどうかです。
JSON Schema(json-schema.org で定義)は、JSONドキュメントの構造・型・制約を記述するための標準仕様です。
JSON Schemaの基本例
{"$schema": "https://json-schema.org/draft/2020-12/schema","type": "object","required": ["id", "name", "email"],"properties": {"id": {"type": "integer","minimum": 1},"name": {"type": "string","minLength": 1,"maxLength": 100},"email": {"type": "string","format": "email"},"role": {"type": "string","enum": ["admin", "editor", "viewer"]}},"additionalProperties": false}
このスキーマが強制するルール:
- ドキュメントは
id、name、emailを必須フィールドとして持つオブジェクトであること idは正の整数であることnameは1文字以上100文字以内の文字列であることemailはemailフォーマットに一致することroleは存在する場合、3つの許可された値のいずれかであること- 追加のフィールドは許可されない
JSON Schemaの主要キーワード
| キーワード | 適用対象 | 説明 |
|---|---|---|
type | すべて | 期待するJSONの型を指定する |
required | オブジェクト | 必須のキーをリストアップする |
properties | オブジェクト | 名前付きキーのスキーマを定義する |
enum | すべて | 値を固定された集合に制限する |
| 数値 | 数値の範囲制約 |
| 文字列 | 文字列の長さ制約 |
pattern | 文字列 | 文字列が一致すべき正規表現パターン |
items | 配列 | 配列要素のスキーマ |
additionalProperties | オブジェクト | 追加のキーを許可するかどうか |
実践的なバリデーションシナリオ
APIレスポンスのバリデーション
サードパーティのAPIを利用する場合、レスポンスの形が予告なく変わることがあります。クライアント境界でレスポンスをバリデーションすることで、そのような変更をアプリケーションロジックの深部でわかりにくいランタイムエラーとして現れる前に、即座に検出できます。
async function fetchUser(id) {const response = await fetch(`/api/users/${id}`);const data = await response.json();// 使用前にバリデーションconst valid = ajv.validate(userSchema, data);if (!valid) {throw new Error(`無効なAPIレスポンス: ${ajv.errorsText()}`);}return data;}
設定ファイルのバリデーション
appsettings.json やカスタムの config.json のような設定ファイルは手書きされることが多く、何かが壊れるまでテストされないことがよくあります。CIパイプラインの一部としてスキーマバリデーションを実行することで、設定ミスによるデプロイを本番環境に届く前に検出できます。
# ajv-cli を使用npx ajv validate -s config.schema.json -d config.json
APIのリクエストボディバリデーション
サーバー側では、受け取ったリクエストボディをバリデーションすることで、不正な入力や悪意のある入力からアプリケーションを保護できます。ajv、zod、joi などのライブラリはNode.jsフレームワークとクリーンに統合できます。
// ajv を使った Express ミドルウェアapp.post('/users', (req, res) => {const valid = ajv.validate(createUserSchema, req.body);if (!valid) {return res.status(400).json({ errors: ajv.errors });}// 有効なリクエストを処理});
バリデーションツール
JSONバリデーションを手軽に行うツールがいくつかあります:
- JSONKit Validate — JSONを貼り付けると行番号付きで即座に構文エラーを報告。インストール不要
- ajv — JavaScript/Node.js向けの最速JSON Schemaバリデーター
- jsonschema — Pythonの標準的なJSON Schemaライブラリ
- json-schema-validator — Java向けの広く使われているライブラリ
効果的なJSONバリデーションのTips
- 境界でバリデーションする — ビジネスロジックの深部ではなく、データがシステムに入る・出る境界でバリデーションを行いましょう。
- 厳格なスキーマを使う —
additionalProperties: falseを設定し、必須フィールドを明示的にマークしましょう。緩いスキーマは本物のバグを見逃します。 - フォーマットバリデーションを含める —
formatキーワード(email、uri、date-time)を使って、意味的に無効な文字列を検出しましょう。 - 構造化されたエラーを返す — バリデーション失敗時は「無効なJSON」だけでなく、失敗したフィールドのパスと制約を返しましょう。
- 無効なデータでテストする — 意図的に不正なデータを渡すテストを書いて、バリデーション層が正しく拒否することを確認しましょう。
まとめ
本番システムにおいてJSONバリデーションはオプションではありません。構文バリデーションはパース可能性を保証し、スキーマバリデーションは正確性を保証します。両者を合わせることで、データの生成者と消費者の間に信頼できる契約が成立します。
JSONKitのValidateツールを使えば、任意のJSONの構文エラーを即座に確認できます——JSONを貼り付けるだけで行番号付きの明確なエラーレポートが表示され、コードに到達する前に問題を修正できます。サインアップ不要、サーバーへのアップロードなし。