JSON

2025年8月12日

はじめに

JSON(JavaScript Object Notation)は、データを構造化して表現するための軽量なテキストフォーマットである。比較的人間が読みやすく、プログラムでも簡単に解析できるため、Web APIや設定ファイルなどで広く利用されている。

名前の通りJavaScriptのオブジェクト表記だが、他の言語でも使われる。

JSONの基本

JSONは、キーと値のペアで構成されるオブジェクトが基本である。オブジェクトは{}で囲まれる。キーと値のペアは"key": valueで表され、カンマ,で区切られる。

{
  "name": "Alice",
  "age": 30,
  "isStudent": false
}

これだけといえばこれだけである。コメントも書けない。コメントを入れたければ、次のように入れるしかない。

{
  "description": "JSONオブジェクトの例",
  "name": "Alice",
  "age": 30,
  "isStudent": false
}

ファイルにする場合の拡張子は.jsonである。

データ型

文字列

"name": "Alice"

文字列はダブルクォーテーション"で囲む。

数値

"age": 30,
"height": 175.5

整数や浮動小数点数を直接記述する。

ブール値

"isStudent": false

trueまたはfalseを使用する。

null値

値が存在しないことをnullで表します

"middleName": null

データ構造

配列

順序付きの配列を[]で表せる。

"hobbies": ["reading", "swimming", "coding"]

オブジェクト

オブジェクトは入れ子にできる。

{
  "person": {
    "name": "Bob",
    "age": 25,
    "address": {
      "city": "Osaka",
      "zip": "530-0001"
    }
  }
}

オブジェクトを配列の要素にすることもできる。

"employees": [
  {
    "name": "Charlie",
    "department": "Engineering"
  },
  {
    "name": "Diana",
    "department": "Marketing"
  }
]

まぜこぜすることもできる。

{
  "company": "Tech Corp",
  "locations": ["Tokyo", "New York", "London"],
  "founded": 2001,
  "ceo": {
    "name": "Eve",
    "age": 45
  }
}

実践的な使用

JSONの検証

書式のチェックだけであれば、Pythonを使って以下のようにすればよい。

$ python -c "import json; json.load(open('config.json')); print('OK')"

JSONスキーマによる検証は、check-jsonschemaでできる。

schema.json

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "age": {
      "type": "integer",
      "minimum": 0
    },
    "email": {
      "type": "string",
      "format": "email"
    }
  },
  "required": ["name", "age"]
}

data.json

{
  "name": "Alice",
  "age": 30,
  "email": "alice@example.com"
}

インストール

$ pip install check-jsonschema

実行

$ check-jsonschema --schemafile schema.json data.json 
ok -- validation done

JSONスキーマは、データの構造や制約(例: 必須フィールド、データ型、値の範囲など)を定義するルールセットであり、これにより、データの整合性を検証したりできる。たとえば、上の例でいうと、ageの設定が抜けていたりすると、次のような結果となる。

$ check-jsonschema --schemafile schema.json data.json
Schema validation errors were encountered.
  data.json::$: 'age' is a required property

Pythonプログラムで検証する場合は、jsonschemaを用いる。

$ pip install jsonschema
# validation.py
import json
from jsonschema import validate, ValidationError

# スキーマの定義
schema = {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer", "minimum": 0},
        "email": {"type": "string", "format": "email"}
    },
    "required": ["name", "age"]
}

# JSONデータの読み込み
data = {
    "name": "Alice",
    "age": 30,
    "email": "alice@example.com"
}

# スキーマに基づく検証
try:
    validate(instance=data, schema=schema)
    print("JSON is valid according to the schema.")
except ValidationError as e:
    print("Invalid JSON:", e.message)

Pythonの時点ではすでにJSONではないので(ただの辞書なので)、JSON以外の検証にも使える。

設定ファイルとしての利用

JSONを設定ファイルとして利用した場合の例を以下に示す。

{
  "app": {
    "name": "My Application",
    "version": "1.0.0",
    "debug": true,
    "log_level": "INFO"
  },
  "database": {
    "host": "localhost",
    "port": 5432,
    "name": "mydb",
    "user": "admin",
    "password": "secret",
    "max_connections": 10
  },
  "server": {
    "host": "0.0.0.0",
    "port": 8000,
    "timeout": 30,
    "allowed_origins": [
      "http://localhost:3000",
      "https://example.com"
    ]
  },
  "special": {
    "features": {
      "feature1": true,
      "feature2": true
    },
    "thresholds": {
      "cpu": 90,
      "memory": 80
    }
  }
}

Pythonでの利用例

# read_json.py
import json
import logging
from typing import Dict, Any

def load_config(config_path: str) -> Dict[str, Any]:
    """JSON設定ファイルを読み込む"""
    with open(config_path, 'r') as file:
        config = json.load(file)
    return config

def setup_logging(config: Dict[str, Any]) -> None:
    """ログ設定を適用"""
    log_level = config['app']['log_level']
    logging.basicConfig(
        level=log_level,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )

def main():
    # 設定ファイルを読み込む
    config = load_config('config.json')
    
    # ログ設定を適用
    setup_logging(config)
    
    # 設定を使用してアプリケーションを構成
    app_name = config['app']['name']
    db_config = config['database']
    server_config = config['server']
    
    logging.info(f"Starting {app_name} version {config['app']['version']}")
    
    # データベース接続(例)
    #db = connect_to_database(db_config)
    
    # サーバー起動(例)
    #start_server(server_config)
    
    # 特別な設定を使用
    if 'feature1' in config['special']['features']:
        logging.info("Feature1 is enabled")
    
    if config['special']['thresholds']['cpu'] > 80:
        logging.warning("High CPU threshold configured")

if __name__ == "__main__":
    main()