JSON

JavaScript 由来の軽量なデータ交換フォーマットで、Web API のデファクトスタンダード

データ形式Web
JSON」の技術書を見る →

JSON とは

JSON (JavaScript Object Notation) は、Douglas Crockford が 2001 年に考案した軽量なデータ交換フォーマットである。標準化されたのは後年で、Crockford 自身が書いた RFC 4627 が最初の文書化にあたり、現行の仕様は 2017 年の RFC 8259 (RFC 7159 を廃止した Standards Track 文書) と ECMA International の ECMA-404 の 2 本立てになっている。文法は両者で同じだが、ECMA-404 は RFC 8259 が相互運用性のために避けるよう勧めている書き方も許しているため、「文法上は通るが相手が受け取れない」余地が残っている。人間にも機械にも読みやすく、ほぼすべてのプログラミング言語でパーサーが提供されている。Web API のレスポンス形式として事実上の標準だ。

データ型

データ型の例を示す。

{
  "string": "Hello",
  "number": 42,
  "float": 3.14,
  "boolean": true,
  "null": null,
  "array": [1, 2, 3],
  "object": { "key": "value" }
}
注意点
文字列"hello"ダブルクォートのみ (シングル不可)
数値42, 3.14Infinity, NaN は不可
真偽値true, false小文字のみ。TRUEyes は使えない
nullnullundefined は不可
配列[1, 2, 3]末尾のカンマは使えない
オブジェクト{"key": "value"}キーは文字列のみ

JSON にないもの

  • コメント (//, /* */)
  • 末尾カンマ ([1, 2, 3,])
  • undefined, Infinity, NaN
  • 日付型 (文字列として "2026-04-01T00:00:00Z" で表現)
  • BigInt

相互運用性の落とし穴

文法が単純な割に、実装差で事故が起きる箇所は決まっている。RFC 8259 が名指しで注意しているのは次の 3 点である。

文字エンコーディング: 閉じたエコシステムの外とやり取りする JSON テキストは UTF-8 で符号化しなければならない。送出側は先頭に BOM (U+FEFF) を付けてはならず、受信側は BOM を読み飛ばしてもよい、という非対称な規定になっている。つまり BOM 付きで保存したファイルが通るかどうかは相手のパーサー次第で、手元では読めるのに送った先で構文エラーになる。

数値の精度: 仕様は数値の範囲と精度に上限を設けることを実装に許しており、IEEE 754 の倍精度浮動小数点数を超える精度を期待しなければ相互運用できる、という書き方になっている。裏を返せば 64 bit 整数はそのまま送れない。JavaScript の JSON.parse は数値を倍精度に丸めるので、19 桁の数値 ID や最小単位を整数で持つ金額を数値型で送ると、エラーも警告も出ないまま下位の桁が変わる。この種の値は文字列として送るのが実務上の答えである。

キーの重複: 同一オブジェクト内のキーは一意にすべき (SHOULD) と書かれているだけで、一意でない場合の挙動は仕様が決めていない。最後のペアだけを採用する実装が多いが、エラーにする実装も、重複を含めてすべて返す実装もある。受信側でスキーマ検証を通していないと、同じ JSON を送受信側が別の意味に読む。

TypeScript での操作

TypeScript での操作のコード例を示す。

// シリアライズ
const json = JSON.stringify({ name: 'Alice', age: 30 });
// '{"name":"Alice","age":30}'

// デシリアライズ (戻り値は any → 型検証が必要)
const data = JSON.parse(json); // any 型

// ✅ Zod でバリデーション + 型推論
import { z } from 'zod';
const UserSchema = z.object({ name: z.string(), age: z.number() });
const user = UserSchema.parse(JSON.parse(json)); // { name: string; age: number }

JSON vs 他のフォーマット

JSON と他のフォーマットの違いを以下にまとめる。

フォーマット用途コメント型の厳密さ
JSONAPI、データ交換不可中程度
YAML設定ファイル、CI/CD可能曖昧
TOML設定ファイル可能厳密
Protocol Buffersマイクロサービス間通信スキーマ定義には書けるが、送るデータには残らない厳密 (スキーマ必須)

DynamoDB と JSON

DynamoDB のアイテムは JSON に似た構造だが、型情報が付与される。

// DynamoDB のアイテム (マーシャリング形式)
{ "userId": { "S": "123" }, "age": { "N": "30" }, "tags": { "L": [{ "S": "admin" }] } }

// AWS SDK v3 のマーシャリングで通常の JSON として扱える
{ "userId": "123", "age": 30, "tags": ["admin"] }

JSON Lines (JSONL)

1 行に 1 つの JSON オブジェクトを記述する形式。ログファイルやストリーミング処理で使われる。

{"timestamp":"2026-04-01T10:00:00Z","level":"INFO","message":"Request received"}
{"timestamp":"2026-04-01T10:00:01Z","level":"ERROR","message":"DB connection failed"}

Athena で S3 上の JSONL ファイルを直接クエリできる。

JSON の理解を深めるには関連書籍が参考になる。

この記事は役に立ちましたか?

関連用語

関連する記事