JSONの構文チェックとJSON Schemaに基づく構造検証の違い
JSONを扱うシステム開発において,テキストの波括弧や引用符の配置が仕様通りかを確かめる構文チェックと,データの中身が要件に合致しているかを確かめるスキーマ検証は異なる処理です.本ツールでは入力されたテキストデータをJavaScriptのJSON.parseによって値へ変換しますが,この過程で元のインデントや重複キー,数値の字句表現が失われる一方,オブジェクトのキー順序は必ずしもすべて失われるわけではありません.
また,極端に大きな数値などの解釈によってJSON.parseの結果がInfinityとなる場合があり,本ツールはそのような値を有限な数値として検証できずに拒絶するため,JSON.parseが常に有限な数値を保証するわけではありません.
本ツールのSchema検証は,構文解析を経てメモリ上に展開されたJSONデータが,指定されたスキーマの制約を満たしているかを照合するものです.検証対象となる根(ルート)のデータは,オブジェクトや配列だけでなく,文字列,数値,真偽値,nullといった単一のスカラー値であっても構いません.
一方で,検証ルールを規定するルートスキーマは,制約を記述したオブジェクト,またはすべてを無条件に許可・拒否する真偽値スキーマ(trueまたはfalse)である必要があり,nullなどのスカラー値をルートスキーマとして与えることは定義エラーとなります.
さらに,JSONデータをCSVの平坦な行構造やXMLの属性とテキストノード,TypeScriptの静的型定義などと相互変換するような場面では,各形式が持つ固有の型情報や意味的な階層構造が欠落しやすくなります.本ツールの検証処理は,現在読み込まれているJSONデータとスキーマの定義を直接突き合わせるものであり,他のデータ形式との変換で失われた情報を復元したり,相互変換処理そのものの妥当性を数学的に証明する機能は持ち合わせていません.
システムの入力境界で受け取ったデータが最低限の期待を満たしているかを機械的に確認するための手段です.
JSONデータの検証は,アプリケーションの信頼性を高める第一歩ですが,それ単体で業務ロジックの完全性やセキュリティを担保できるわけではありません.スキーマ定義が形式的に正しく,データがその制約を満たしていたとしても,IDが実在するか,金額の計算が業務規則に合致しているかといった意味論的な検証は別途必要となります.
また,本ツールにおける数値の有限性や安全な整数の範囲チェックはツール側の処理限界に基づく安全策であり,JSON Schema仕様そのものがそれらの数値を無効と定めているわけではない点にも理解が必要です.
本ツールで対応しているSchemaキーワードとその判定範囲
本ツールの検証エンジンは,JSON Schema Draft-07仕様の中から日常的なデータ構造チェックに多用される特定のキーワードに絞り込んだ対応部分集合を提供します.具体的にサポートしている検証キーワードは,データの基本型を判定するtype,必須プロパティを指定するrequired,オブジェクトと配列の子要素を定義するpropertiesおよびitems,配列長を制限するminItemsとmaxItems,文字列長を制約するminLengthとmaxLength,正規表現による検査を行うpattern,数値の範囲を規定するminimumとmaximum,許容される値のリストを定めるenumです.
また,すべてのデータを無条件に合格とするtrue,常に不合格とするfalseの真偽値スキーマにも対応しています.
型を指定するtypeキーワードでは,7つの基本型名(null,boolean,object,array,number,string,integer)の単一指定に加え,重複のない配列による型ユニオン(例: ["string", "number"])も受理されます.
検証対象データは任意の有効なJSONルート値(オブジェクト,配列,プリミティブ値)を許容し,スキーマ側はオブジェクトまたは真偽値スキーマである必要があります.メタデータとしては,$schemaはルートのみでDraft-07の公式URI(末尾の#の有無を許容)を受け付け,$idは文字列として受理されますがURI検証や識別子の名前解決は実装されていません.
また,アノテーションであるtitle,description,default,examplesは検証言明として扱われず,default値がデータへ自動挿入されることもありません.
本ツールが採用している製品ポリシーの重要な特徴は,Draft-07の標準的な振る舞いとは異なり,未知のキーワードや未対応のキーワードが含まれていた場合に「フェイルクローズ(安全側に倒して処理を停止)」する点にあります.一般的なDraft-07仕様では未知のキーワードは単に無視することが推奨されていますが,本ツールでは$refによる参照,formatによる書式検証,constによる単一値固定,additionalPropertiesによる追加プロパティ制御,anyOfやoneOfといった複合スキーマなどの未対応キーワードが存在する場合,制約のすり抜けを防ぐためにスキーマ定義エラーとして検証を即座に中断します.
加えて,スキーマの構文検査はデータ側に該当プロパティが存在するかどうかにかかわらず,定義全体の木構造を走査して事前に実施されます.たとえばデータ側には存在しない任意のプロパティ定義の中に不正な正規表現や未知のキーワード,不正な型名が含まれていた場合であっても,検証開始前の静的チェックによって問題が検出されます.
限られたキーワードのみを厳格にサポートすることで,予期せぬ制約の解釈漏れを排し,安全で明瞭な判定結果を得られる設計となっています.
オブジェクトと配列における再帰的な階層データの検証手法
JSONデータは,オブジェクトの中にさらにオブジェクトや配列を含めることで,柔軟で複雑な階層構造を表現できます.本ツールでは,propertiesキーワードやitemsキーワードに定義された子要素向けのスキーマを読み取り,データの階層を深さ優先で辿りながら再帰的に検証を進めていきます.
入力例として,ユーザー情報の中に複数の連絡先が配列として含まれ,それぞれの連絡先がさらに電話番号と種別のプロパティを持つような多重構造のデータを検証する場合でも,各階層に対応する制約ルールを順次適用します.なお,配列要素のスキーマを定義するitemsには単一のスキーマ(オブジェクトまたは真偽値)のみを指定可能であり,要素ごとに異なる定義を割り当てるタプル配列形式には対応していません.
オブジェクトの検証においては,プロパティの探索時にJavaScriptのプロトタイプ汚染や意図しないプロパティ継承の影響を受けないよう,入力データ自身が直接保有するキー(own property)のみを判定対象とします.requiredに指定された必須プロパティ配列は重複のない文字列で構成されている必要があり,空の配列を指定することも構文上有効です.
一方,propertiesに宣言されていないプロパティがデータ側に含まれていても,本サブセットでは追加プロパティの禁止(additionalProperties)を実装していないため,未宣言プロパティの存在そのものによって検証が失敗することはありません.また,propertiesで定義された任意の項目がデータ側で省略されている場合も,requiredに含まれていない限り問題なく許容されます.
配列の長さ制約であるminItemsおよびmaxItemsは,itemsキーワードの有無とは独立して動作します.要素に対する詳細な型定義がスキーマ上に存在しない場合であっても,配列の要素数だけを制限する目的でこれらのキーワードを単独または組み合わせて利用することが可能です.
もしminItemsに10を指定し,maxItemsに5を指定するような論理的に両立不可能な制約が記述されていた場合でも,それはスキーマ自体の定義構文としては有効であり,単にいかなる配列も満たすことができない条件として評価されます.
階層の走査にあたっては,極端に深いネストによるスタックオーバーフローを防ぐため,ルートを1とする深さ64までの上限値が設けられています.また,1つのドキュメント内で訪問可能なノード数も最大20,000ノードに制限されています.深いネストを持つデータ構造の検証では,親要素から子要素へと制約が意図通りに伝播しているかを確認するとともに,これらの探索上限に達して処理が打ち切られないよう,実用的なデータ規模に収まっているかを意識することが重要です.
文字列,数値,および列挙型制約の計算と評価規則
文字列や数値に対する細かな制約は,ブラウザ内の実行環境が提供する標準仕様に沿って慎重に評価されます.文字列の長さ制約であるminLengthおよびmaxLengthの評価では,JavaScript文字列のUTF-16コード単位長(lengthプロパティ)をそのまま用いるのではなく,Unicodeのコードポイント単位で文字数を反復計数する処理が行われます.
これにより,絵文字や特定の漢字などのサロゲートペアで表現される文字が含まれている場合でも,文字コードの断片ではなくコードポイント単位の自然な文字数として長さが判定されます.ただし,書記素クラスタ(合字や結合文字列)の単位での判定とは異なる点に留意する必要があります.
正規表現パターンを指定するpatternキーワードは,JavaScriptのRegExpコンストラクタにUnicodeフラグ("u")を付与して生成され,部分一致(substring match)として評価されます.スキーマ上に暗黙的な先頭記号(^)や末尾記号($)が付与されることはないため,文字列全体の一致を求めたい場合は正規表現内に明示的なアンカーを記述する必要があります.
また,patternに指定された文字列の構文が正規表現として不正である場合は,データ検証を行う前段階のスキーマ検査で即座にエラーとなります.なお,正規表現の解釈は実行ブラウザのJavaScriptエンジンに依存するため,環境間で極めて特殊な構文の挙動が完全に同一とならない可能性もあります.
数値の範囲を規定するminimumおよびmaximumは,指定された境界値を含める(inclusive)判定を行います.小数の比較においてもJavaScriptの倍精度浮動小数点数の演算規則が適用されますが,本ツールの入力制約として,スキーマおよびデータ内の数値は有限数(Number.isFinite)であり,整数値は安全な整数(Number.isSafeInteger)の範囲内である必要があります.
また,符号付きゼロ(-0)は通常の数値0と等価なものとして扱われます.もしminimumに100,maximumに50が指定されているような矛盾した範囲であっても,定義エラーではなく「どの数値も合格できない有効なスキーマ」として振る舞います.
許容される値のリストを定義するenumキーワードでは,単純なスカラー値のみならず,ネストされたオブジェクトや配列を含む構造的な深層比較(ディープ等価判定)が実行されます.この比較では,オブジェクトのキーの記述順序は無視され,配列の要素の出現順序は厳密に保持されます.
さらに,本ツールの製品ポリシーとして,enumに指定する配列は空であってはならず,リスト内の要素同士が構造的に一意(重複なし)でなければなりません.Draft-07の標準仕様ではenum内の重複はSHOULD(推奨)違反にとどまりますが,本ツールでは厳格な品質維持のため,重複した要素を含むenum定義はスキーマエラーとして拒絶されます.
エラーパスの構造と検証失敗時の問題箇所の特定方法
検証においてスキーマ定義の不正やデータとの不一致が見つかった場合,システムはどこでどのような違反が発生したのかを明確に特定できる形式で結果を報告します.本ツールでは,問題が発生した位置を示すパス情報として,RFC 6901に準拠したJSON Pointer形式を採用しています.
ルート要素は空文字列("")で表現され,階層が深くなるごとにスラッシュ区切りでプロパティ名や配列のインデックス番号が連結されます.プロパティ名にチルダ(~)やスラッシュ(/)が含まれる場合は,仕様通り「~0」および「~1」にエスケープ処理が行われるため,従来の曖昧なドット記法やブラケット記法に比べて正確な位置特定が可能です.
検証中に報告される問題は,その性質に応じて発生元(source)が明確に区別されます.入力テキストの構文エラーはスキーマ側で起因すれば「schema」,データ側で起因すれば「instance」となり,スキーマ制約への不適合も「instance」エラーとして記録されます.
ツリー階層や数値入力の上限超過も違反の起因に応じてschemaまたはinstanceを維持しますが,全体ステップ数上限,エラー件数上限,出力文字予算,Workerタイムアウトなどの処理制約に起因する中断は「runtime」エラーに分類されます.すべての構文エラーがschemaになるわけではなく,またすべての制限超過がruntimeになるわけでもありません.
大量のエラーによる過負荷を防ぐため,1回の検証で検出可能なエラー件数は100件までに制限されており,101件目のエラーが検出された時点,またはエラーパス,引数文字列,エラーコードで消費されるテキスト予算が200,000 UTF-16コード単位を超過した時点で処理は中断(blocked)されます.
この中断時には,それまでに収集された部分的なエラー一覧はすべて破棄され,制限超過を示す通知メッセージのみが表示されます.エラーがちょうど100件の場合は不合格(invalid)として完了できますが,中断は合格を意味するものではなく,全件網羅や厳密なメモリ消費の回避を保証するものでもありません.
表示されるJSON Pointerパスを修正の道標として活用する際は,配列のインデックスやオブジェクトのキーがどのスキーマ制約に抵触したのかを照合します.たとえば「/users/0/email」においてpatternの不一致が示されている場合,該当する配列要素の文字列形式を見直す必要があります.
ただし,配列の要素の抜け漏れや順序の狂いがある場合,後ろに続く要素のエラーパスが本来の意図からずれて報告されることがあるため,エラー箇所単体だけでなく前後のデータ構造全体とスキーマ定義を見比べることが肝要です.
未対応の高度な機能と正式なバリデーターを使う場面
本ツールの構文解析・正規表現コンパイル・再帰的検証処理はすべて専用のWeb Worker上で非同期に実行され,メインスレッドへの同期フォールバックは行われません.メインスレッドでは実行前にスキーマとデータの入力をそれぞれ100,000 UTF-16コード単位以下か確認し,検証開始後はWorkerの起動やメッセージ転送時間を含めて1,000ミリ秒の待機時間を超えた場合にWorkerの終了を要求しますが,ブラウザのバックグラウンド動作やホストの負荷により遅延が生じることがあります.
これらの実行予算や100,000ステップ上限は目安の上限値であり,ハードなCPU時間やメモリ消費の完全な抑制,あらゆるリソース枯渇の防止を保証するものではありません.
ユーザーインターフェース上では,検証処理の実行中にはボタンが無効化され,進行中の重い処理を手動で中断できる「Stop」ボタンが用意されています.また,入力欄の編集,プリセットの選択,クリア操作,再実行,またはページからの離脱が行われた際には,即座に古いWorkerが破棄され,過去の検証結果が表示に残り続ける(stale green)ことがないよう設計されています.
検証結果の表示においても,スキーマの構文違反,データの制約違反,処理上限到達によるブロック,手動停止の各状態が厳密に区別して提示されます.
本ツールはフロントエンドにおける日常的な構造確認を素早く行うための補助ツールであり,Draft-07のすべての仕様を網羅した完全な適合バリデーターではありません.外部スキーマファイルを動的にフェッチする$ref機能やIDによるURI名前解決,日付やURIなどの書式を照合するformatキーワード,追加プロパティの禁止(additionalProperties),データの組み合わせに応じた条件分岐など,複雑なシステム間連携で要求される厳格な検証には未対応です.
したがって,エンタープライズ環境のAPI仕様テストや,複数ファイルにまたがる大規模なスキーマ群の検証には,Ajvなどの専用の検証ライブラリを組み込んだビルドパイプラインを利用してください.
本ツールの検証を通過したという結果は,あくまで提供されているDraft-07の限定された部分集合ルールにおいて,現時点で入力されたデータに不一致が検出されなかったことを意味するに過ぎません.入力されたJSONペイロードが外部サーバーへ送信されることはなく,ブラウザ内で完結して処理されますが,アプリケーションスキーマのビジネス妥当性やデータベース整合性を保証するものではないことを前提とし,要件に応じた検証ツールの使い分けを行うことが推奨されます.