JSON Schemaを理解する
JSON Schemaの定義、検証、実用例を学びます。データ検証、API契約、自動ドキュメント生成のための完全ガイド。
Big JSON Team
• Technical WriterExpert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.
# JSON Schemaを理解する
JSON Schemaは、JSONデータの構造を定義し検証するための強力なツールです。
JSON Schemaとは
JSON Schemaは、JSONデータの構造、内容、意味を記述するための語彙です。
主な用途
- ✅ データ検証 - 入力データが正しい形式かチェック
- ✅ ドキュメント - データ構造を文書化
- ✅ API契約 - クライアントとサーバー間の契約
- ✅ コード生成 - スキーマから型を自動生成
- ✅ テスト - データの整合性をテスト
基本的なスキーマ
シンプルな例
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number",
"minimum": 0
}
},
"required": ["name"]
}
有効なデータ
{
"name": "田中太郎",
"age": 30
}
無効なデータ
{
"age": 30
}
// エラー: "name" は必須
{
"name": "田中太郎",
"age": -5
}
// エラー: "age" は0以上でなければならない
データ型
基本型
string
{
"type": "string",
"minLength": 3,
"maxLength": 50,
"pattern": "^[A-Za-z]+$"
}
number / integer
{
"type": "number",
"minimum": 0,
"maximum": 100,
"multipleOf": 5
}
boolean
{
"type": "boolean"
}
null
{
"type": "null"
}
複合型
object
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" }
},
"required": ["name"],
"additionalProperties": false
}
array
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"maxItems": 5,
"uniqueItems": true
}
検証キーワード
文字列の検証
{
"type": "string",
"minLength": 3,
"maxLength": 20,
"pattern": "^[a-zA-Z0-9_]+$",
"format": "email"
}
フォーマット:
email- メールアドレスuri- URIdate- 日付 (YYYY-MM-DD)time- 時刻 (HH:MM:SS)date-time- 日時 (ISO 8601)ipv4- IPv4アドレスipv6- IPv6アドレス
数値の検証
{
"type": "number",
"minimum": 0,
"maximum": 100,
"exclusiveMinimum": 0,
"exclusiveMaximum": 100,
"multipleOf": 0.01
}
配列の検証
{
"type": "array",
"items": { "type": "number" },
"minItems": 1,
"maxItems": 10,
"uniqueItems": true,
"contains": { "type": "number", "minimum": 5 }
}
オブジェクトの検証
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" }
},
"required": ["name"],
"minProperties": 1,
"maxProperties": 10,
"additionalProperties": false
}
実用例
ユーザースキーマ
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/user.schema.json",
"title": "User",
"description": "ユーザーエンティティ",
"type": "object",
"properties": {
"id": {
"description": "ユーザーの一意なID",
"type": "integer",
"minimum": 1
},
"name": {
"description": "ユーザーの氏名",
"type": "string",
"minLength": 1,
"maxLength": 100
},
"email": {
"description": "メールアドレス",
"type": "string",
"format": "email"
},
"age": {
"description": "年齢",
"type": "integer",
"minimum": 0,
"maximum": 150
},
"roles": {
"description": "ユーザーの役割",
"type": "array",
"items": {
"type": "string",
"enum": ["user", "admin", "moderator"]
},
"uniqueItems": true
},
"created": {
"description": "作成日時",
"type": "string",
"format": "date-time"
}
},
"required": ["id", "name", "email"],
"additionalProperties": false
}
商品スキーマ
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Product",
"type": "object",
"properties": {
"productId": {
"type": "string",
"pattern": "^[A-Z]{2}\\d{6}$"
},
"name": {
"type": "string",
"minLength": 1
},
"price": {
"type": "number",
"minimum": 0,
"multipleOf": 0.01
},
"inStock": {
"type": "boolean"
},
"tags": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true
},
"dimensions": {
"type": "object",
"properties": {
"length": { "type": "number", "minimum": 0 },
"width": { "type": "number", "minimum": 0 },
"height": { "type": "number", "minimum": 0 }
},
"required": ["length", "width", "height"]
}
},
"required": ["productId", "name", "price"]
}
高度な機能
enum(列挙)
{
"type": "string",
"enum": ["red", "green", "blue"]
}
const(定数)
{
"type": "string",
"const": "admin"
}
oneOf(いずれか1つ)
{
"oneOf": [
{ "type": "string" },
{ "type": "number" }
]
}
anyOf(いずれか)
{
"anyOf": [
{ "type": "string", "maxLength": 5 },
{ "type": "number", "minimum": 0 }
]
}
allOf(すべて)
{
"allOf": [
{ "type": "object" },
{
"properties": {
"name": { "type": "string" }
}
},
{
"properties": {
"age": { "type": "number" }
}
}
]
}
not(否定)
{
"not": {
"type": "string"
}
}
条件付きスキーマ
if/then/else
{
"type": "object",
"properties": {
"country": { "type": "string" },
"postalCode": { "type": "string" }
},
"if": {
"properties": {
"country": { "const": "Japan" }
}
},
"then": {
"properties": {
"postalCode": {
"pattern": "^\\d{3}-\\d{4}$"
}
}
},
"else": {
"properties": {
"postalCode": {
"pattern": "^[A-Z0-9]+$"
}
}
}
}
参照と再利用
$ref
{
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" }
}
}
},
"type": "object",
"properties": {
"billingAddress": { "$ref": "#/$defs/address" },
"shippingAddress": { "$ref": "#/$defs/address" }
}
}
JavaScriptでの検証
Ajv(最も人気)
インストール
npm install ajv
基本的な使い方
const Ajv = require('ajv');
const ajv = new Ajv();
// スキーマ
const schema = {
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'number', minimum: 0 }
},
required: ['name']
};
// スキーマをコンパイル
const validate = ajv.compile(schema);
// データを検証
const data = {
name: '田中太郎',
age: 30
};
const valid = validate(data);
if (valid) {
console.log('データは有効です');
} else {
console.log('検証エラー:', validate.errors);
}
カスタムフォーマット
const Ajv = require('ajv');
const addFormats = require('ajv-formats');
const ajv = new Ajv();
addFormats(ajv);
// カスタムフォーマット
ajv.addFormat('phone-jp', /^\d{2,4}-\d{2,4}-\d{4}$/);
const schema = {
type: 'string',
format: 'phone-jp'
};
const validate = ajv.compile(schema);
console.log(validate('03-1234-5678')); // true
console.log(validate('invalid')); // false
Pythonでの検証
jsonschema
インストール
pip install jsonschema
使い方
from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number", "minimum": 0}
},
"required": ["name"]
}
# 有効なデータ
data = {
"name": "田中太郎",
"age": 30
}
try:
validate(instance=data, schema=schema)
print("データは有効です")
except ValidationError as e:
print(f"検証エラー: {e.message}")
API開発での使用
Express.js での検証
const express = require('express');
const Ajv = require('ajv');
const app = express();
const ajv = new Ajv();
app.use(express.json());
// スキーマ
const userSchema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' },
age: { type: 'number', minimum: 0 }
},
required: ['name', 'email']
};
const validateUser = ajv.compile(userSchema);
// ミドルウェア
function validateRequest(schema) {
return (req, res, next) => {
const valid = schema(req.body);
if (!valid) {
return res.status(400).json({
error: 'Validation failed',
details: schema.errors
});
}
next();
};
}
// ルート
app.post('/api/users', validateRequest(validateUser), (req, res) => {
// データは検証済み
res.json({ success: true, data: req.body });
});
app.listen(3000);
OpenAPI/Swagger との統合
openapi: 3.0.0
paths:
/users:
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
components:
schemas:
User:
type: object
properties:
name:
type: string
minLength: 1
email:
type: string
format: email
required:
- name
- email
ベストプラクティス
1. 明確な説明を追加
{
"type": "object",
"description": "ユーザーエンティティ",
"properties": {
"name": {
"type": "string",
"description": "ユーザーの氏名"
}
}
}
2. デフォルト値を提供
{
"type": "object",
"properties": {
"role": {
"type": "string",
"default": "user"
}
}
}
3. 例を含める
{
"type": "string",
"format": "email",
"examples": [
"user@example.com",
"test@test.jp"
]
}
4. additionalPropertiesを適切に設定
{
"type": "object",
"properties": {
"name": { "type": "string" }
},
"additionalProperties": false
}
ツールとリソース
オンラインツール
エディタサポート
- VS Code - JSON Schema検証とオートコンプリート
- IntelliJ IDEA - 組み込みサポート
- JSONBuddy - 専用エディタ
まとめ
クイックリファレンス
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"field": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"pattern": "^[A-Za-z]+$",
"format": "email"
}
},
"required": ["field"],
"additionalProperties": false
}
よく使う検証
// JavaScript(Ajv)
const ajv = new Ajv();
const validate = ajv.compile(schema);
const valid = validate(data);
// Python
from jsonschema import validate
validate(instance=data, schema=schema)
JSON Schemaで、データの整合性と品質を保証しましょう!