コードを書き始めて1週間以上経っているなら、ほぼ間違いなくJSONに出会ったことがあるはずです。 REST APIのレスポンス、設定ファイル、データベースのドキュメント、ブラウザストレージ、ログなど、あらゆる場所に登場します。 しかし、JSONとは一体何なのか、そしてなぜWebを席巻するフォーマットになったのでしょうか?

JSONはJavaScript Object Notationの略です。名前に反して、言語に完全に 依存せず、主要なプログラミング言語すべてにライブラリが存在します。 ダグラス・クロックフォードが 2000年代初頭に、ブラウザとサーバー間の通信におけるXMLのよりシンプルな代替手段として形式化しました。仕様は ECMA-404としても 標準化されており、名刺1枚に収まるほど小さい — それが勝因の一つでもあります。

JSONは実際どんな見た目なのか?

こちらがユーザーオブジェクトを表すJSONの一例です。このひとつの例だけで、JSONがサポートする6つのデータ型すべてをカバーしています:

json
{
  "name": "Alice",
  "age": 30,
  "score": 98.5,
  "active": true,
  "nickname": null,
  "tags": ["developer", "blogger"],
  "address": {
    "city": "Berlin",
    "country": "Germany"
  }
}

JSONの6つのデータ型

JSONがサポートする値の型は、ちょうど6つ。これだけです。このシンプルさこそが特長 — 午後ひとつでフォーマット全体を学べます。

json
{
  "string":  "Hello, world",
  "integer": 42,
  "float":   3.14159,
  "boolean": true,
  "nothing": null,
  "array":   [1, "two", false, null],
  "object":  { "nested": true }
}
  • 文字列(String) — ダブルクォートで囲まれた任意のテキスト。"hello""2024-01-01"""はすべて有効な文字列です。
  • 数値(Number) — 整数または浮動小数点数。intとfloatの区別はありません。注意:NaNInfinityは有効なJSON数値ではありません
  • 真偽値(Boolean)trueまたはfalse。小文字のみです。
  • Null — 「値なし」を表します。まだ設定されていないオプショナルなフィールドに便利です。
  • 配列(Array) — 順序付きの値のリスト。型の混在が可能で、[1, "two", true, null]も完全に合法です。
  • オブジェクト(Object) — キーと値のペアの集合。キーはダブルクォートで囲まれた文字列でなければなりません

実世界のAPIレスポンス

GET /api/users/42を呼び出したときの、実際のREST APIレスポンスはこんな感じになるかもしれません。 オブジェクトと配列をネストして、より豊かなデータを表現している点に注目してください:

json
{
  "id": 42,
  "username": "alice_dev",
  "email": "[email protected]",
  "createdAt": "2023-06-15T09:30:00Z",
  "preferences": {
    "theme": "dark",
    "notifications": true,
    "language": "en"
  },
  "roles": ["user", "editor"],
  "lastLogin": "2024-01-10T14:22:00Z",
  "stats": {
    "postsPublished": 27,
    "commentsWritten": 154,
    "likesReceived": 489
  }
}

JavaScriptではalice_devのテーマ設定にuser.preferences.themeで アクセスでき、最初のロールはuser.roles[0]で取得できます。 言語のプリミティブへこのように自然にマッピングされることこそが、JSONを扱うのが楽に感じられる理由です。

JSONの構文ルール — 誰もがハマる落とし穴

JSONはシンプルに見えますが、いくつか厳格なルールがあります。ひとつ間違えるだけで、ペイロード全体のパースが失敗します。 私が最もよく見かけるミスは次のとおりです:

  • キーはダブルクォートで囲む必要があります。 {"name": "Alice"}は有効。{name: "Alice"}は無効です。これはクォートなしのオブジェクトキーが許されるJavaScriptから来た開発者がハマるポイントです。
  • 末尾カンマはNG。 {"a": 1, "b": 2,}はパースエラーになります。JavaScriptは寛容ですが、JSONの仕様はそうではありません。
  • コメントは書けません。 ///* */コメントはJSONには存在しません。コメント付きの設定ファイルが必要なら、YAMLやTOMLを検討してください。
  • undefinedは存在しません。 JavaScriptのundefinedはJSONには存在しません。値が欠けている場合はnullを使いましょう。
  • 文字列はダブルクォートを使用する必要があります。 {'key': 'value'}のようにシングルクォートを使った文字列は無効なJSONです。
  • 先頭のゼロはNG。 042は無効。420.42はOKです。
プロのコツ: JSONをどこかに貼り付けてパースエラーが出た場合、犯人はほぼ確実に 次のいずれかです:末尾カンマ、シングルクォートのキー、紛れ込んだコメント。問題の原因となっている正確な行を特定するには、 JSONバリデーターに貼り付けてみましょう。

なぜJSONがWebを制したのか

JSON以前、XMLが王様でした。典型的なXMLのAPIレスポンスは冗長で、きちんとしたXMLパーサーが必要で、 言語と戦っているような感覚でした。JSONはJavaScriptの組み込み JSON.parse()で パースでき、ライブラリは不要です。通信データが小さく、一目で読め、開発者が日々使っているオブジェクトや配列に直接マッピングされました。

2000年代後半までに、多くの公開APIがXMLと並行してJSONを提供し始めました。2010年代初頭には、 多くがXMLのサポートを完全に打ち切りました。今日、どんなREST APIでもデフォルトの想定はJSONです。 多くの文脈でRESTを置き換えたGraphQLでさえ、 レスポンス形式には依然としてJSONを使用しています。

JSONはサポートしていないものでも定義される

JSONの制約の一部は、シンプルで相互運用性を保つための意図的な設計判断です:

  • 日付型がない。 日付はただの文字列です。慣習としてISO 8601形式が使われます:"2024-01-15T09:30:00Z"
  • バイナリデータがない。 ファイルや画像は通常、Base64エンコードして文字列にします。
  • 関数値がない。 {"fn": function(){} }は無効です。JSONは純粋なデータであり、コードではありません。
  • 重複キーがない。 仕様上は技術的に許可されていますが、動作は未定義です。実際には、パーサーは最後の値を採用します。

JSONを扱うのに便利なツール

JSONを扱う際に頻繁に頼ることになるツールをいくつか紹介します: ミニファイされたレスポンスを整形するJSONフォーマッター、 構文エラーを見つけるJSONバリデーター、 本番用にJSONを圧縮するJSONミニファイアー、 そしてループを書かずに深くネストされたデータをクエリできるJSON Path

公式仕様は json.orgにあり、 読む価値は本当にあります — 10分ほどでフォーマットを完全に理解できます。 IETFの正式仕様は RFC 8259で、 議論に決着をつける必要が出たときに役立ちます。

まとめ

JSONは軽量で人間に読みやすいデータ形式で、6つの値の型 — 文字列、数値、真偽値、 null、配列、オブジェクト — の上に構築されています。厳格な構文ルールがありますが、一度覚えてしまえば驚くようなところはありません。 JSONがここまで遍在する存在になったのは、最も強力なフォーマットだからではなく、現実のデータニーズの95%をカバーする 最もシンプルなフォーマットだからです。Webに関わるものを作っているなら、JSONを理解することは 任意ではなく、土台です。