この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
JSONのValidationをしたい
JSONがデータのフォーマットとして使われだして久しいですが、
現在ではREST APIのやり取り、ElasticsearchやMongoDBでの通信、設定ファイルなど
さまざまな場所で使用されています。
データ形式がシンプルで、柔軟性があるのがJSONの特徴ですが、
データの定義をしっかり決めたいときもあります。
JSONのValidationをする必要があり、
JSON SchemaやJSONのValidationを使用したのでその紹介をします。
quickType
ここでも紹介されていますが、quicktypeとは
JSON Schemaからいろいろな言語コード(Swift, Go, Rust,JavaScript等)を生成したり、
JSONデータからJSON Schemaを生成したりできるツールです。
JSON SchemaはJSONを記述したり検証したりするための設計書のようなもので、
どんなフィールドがあるとか、そのフィールドが必須なのか等がわかります。
//quicktypeで生成したJSON Schema
{
"$schema": "http://json-schema.org/draft-06/schema#",
"$ref": "#/definitions/Schema",
"definitions": {
"Schema": {
"type": "object",
"additionalProperties": false,
"properties": {
"foo": {
"type": "string"
}
},
"required": [
"foo"
],
"title": "Schema"
}
}
}
quicktypeをcliで使う
npmを使えばインストールできます。
Globalオプションでインストールしましょう。
% npm install -g quicktype
では、JSON SchemaをJSONから生成してみます。JSONデータをもとにschema.jsonが生成されます。
% echo '{"foo" : "bar"}' | quicktype -o schema.json --lang schema
% cat schema.json
{
"$schema": "http://json-schema.org/draft-06/schema#",
"$ref": "#/definitions/Schema",
"definitions": {
"Schema": {
"type": "object",
"additionalProperties": false,
"properties": {
"foo": {
"type": "string"
}
},
"required": [
"foo"
],
"title": "Schema"
}
}
}
これはコマンドラインから実行する方法ですが、今回はJavaScriptのコードから
quicktypeを実行してJSON Schemaを生成してみましょう。
環境
今回使用した動作環境は以下のとおりです。
- OS : MacOS X 10.14.5
- node.js : v12.9.0
quicktype-core
コード内でJSON Schemaを生成方法について調べたところ、quicktype-coreを使えば
コード内でSchemaの生成などができるようになるとのことです。
npmをつかってインストールしましょう。
% npm install quicktype-core
quicktype-coreライブラリを使って任意のJSON文字列からJSON Schemaを生成してみます。
//sample.js
const {InputData, JSONSchemaTargetLanguage,
jsonInputForTargetLanguage, quicktypeMultiFileSync} = require("quicktype-core");
//JSON Schema生成元モデル
const json = "{\"foo\" : 10,\"bar\": \"abc\"}";
const input = new InputData();
const srcJsonData = {name: 'SampleSchema', samples: }
const makeInput = () => jsonInputForTargetLanguage(new JSONSchemaTargetLanguage(), undefined, false)
input.addSourceSync("json", srcJsonData, makeInput)
const qtResult = quicktypeMultiFileSync({
lang: new JSONSchemaTargetLanguage(),
inputData: input
});
//生成したスキーマ
const schema = JSON.parse(qtResult.get("stdout").lines.join(''));
console.log(schema);
sample.jsを実行してみると、JSON Schemaが取得できるようになりました。
% node sample.js
{
'$schema': 'http://json-schema.org/draft-06/schema#',
'$ref': '#/definitions/SampleSchema',
definitions: {
SampleSchema: {
type: 'object',
additionalProperties: false,
properties: [Object],
required: [Array],
title: 'SampleSchema'
}
}
}
ajvつかってvalidation
JSON Schemaを取得できたら、対象のJSONがそのSchemaに対してvalidかどうかチェックします。
ajvというJSON Schema Validatorを使ってチェックしましょう。
% npm install ajv
さきほどのプログラムに、ajvを使ったvalidationを追加します。
・・・
const Ajv = require('ajv');
const ajv = new Ajv({allErrors: true});
ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));
const testValidJson = {"foo": 40,"bar":"def"};
var valid = ajv.validate(schema, testValidJson);
console.log(valid);
testValidJsonはJSON Schema的にvalidなので問題ありません。
では、↓のようにJSON SchemaにあっていないJSONにしてみましょう。
・・・
const Ajv = require('ajv');
const ajv = new Ajv({allErrors: true});
ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));
const testInvalidJson = {"foo": "aaa","buzz":[]};
valid = ajv.validate(schema, testInvalidJson);
if (!valid) console.log(ajv.errors);
JSON Schemaと合致していないので、エラーが表示されます。
% node sample.js
[
{
keyword: 'additionalProperties',
dataPath: '',
schemaPath: '#/definitions/SampleSchema/additionalProperties',
params: { additionalProperty: 'buzz' },
message: 'should NOT have additional properties'
},
{
keyword: 'type',
dataPath: '.foo',
schemaPath: '#/definitions/SampleSchema/properties/foo/type',
params: { type: 'integer' },
message: 'should be integer'
},
{
keyword: 'required',
dataPath: '',
schemaPath: '#/definitions/SampleSchema/required',
params: { missingProperty: 'bar' },
message: "should have required property 'bar'"
}
]
型違いやフィールド有無についてエラーが表示されています。
※設定によりエラーにするかどうかの変更も可能
これでJSONのValidationチェックができるようになりました。