一言でいうと
JSONは、リストや辞書みたいな感じでデータを構造化するためのテキストベースのやり方。これのおかげで、コンピュータにとっても人間にとっても、情報の読み書きや交換が驚くほど簡単になります。
解決する問題
2000年代初頭のウェブを想像してみてください。もし、ページ全体をリロードせずにウェブページが新しいデータを取得できるようにしたい(AJAXなんていうイケてる新技術ですね)と思ったら、おそらくXMLと格闘していたことでしょう。XML(eXtensible Markup Language)は、当時データ交換の王者として君臨していました。パワフルで、厳格で…そして、はっきり言って、ちょっと厄介なヤツでした。
XMLドキュメントは冗長です。すべてのデータが開始タグと終了タグでラップされています。
<user>
<id>123</id>
<name>Alex</name>
<isAdmin>true</isAdmin>
</user>
これは最悪というわけではありませんが、ゴテゴテしています。もっと重要なのは、ブラウザの言語であるJavaScriptでこれをパースするのが苦痛だったということです。複雑なドキュメントオブジェクトモデル(DOM)をナビゲートし、ノードや属性、テキストコンテンツを扱わなければなりませんでした。まるで、クルミを割るのにスレッジハンマーを使っているような気分でした。
そこに登場したのが、後にYahoo!となる会社で働いていた開発者、ダグラス・クロックフォードです。彼は、ある素晴らしいことに気づきました。JavaScriptには、構造化データを定義するための完璧で、組み込みのやり方がすでに存在するじゃないか、と。それは「オブジェクトリテラル記法」と呼ばれていました。
// これは、まんま普通のJavaScriptです!
var user = {
"id": 123,
"name": "Alex",
"isAdmin": true
};
クロックフォードは、JavaScript構文のこのサブセットが、それ自体で素晴らしいデータフォーマットであることに気づきました。軽量で、人間が読みやすく、そして—これが最大の武器だったのですが—JavaScriptでのパースが非常に簡単だったのです。基本的にはeval()でいけちゃうんです(もっとも、セキュリティ上の理由から、今ではJSON.parse()のようなより安全なメソッドが使われますが)。
彼はこのフォーマットを正式化し、JavaScript Object Notation(JSON)と名付け、それを説明するシンプルな1ページのウェブサイトを作成しました。それは、XMLよりもかさばらず、ウェブ環境にネイティブなデータフォーマットが必要だという問題を解決しました。JSONは燎原の火のように広まり、API、設定ファイル、その他無数のアプリケーションでデファクトスタンダードとなりました。JSONが勝利したのは、シンプルで、実用的で、そしてそれが仕えるために設計された言語そのものから生まれたからです。
内部の仕組み
JSONの核となるのは、データをテキストとして書き留めるための一連のルールにすぎません。データ構造のための普遍的な設計図のようなものだと考えてください。構造を作る方法は2つしかなく、その中に入れられるデータ型はシンプルな6種類だけです。
基本要素:データ型
JSONのエレガントさは、そのミニマリストな値の型のセットから来ています。JSONのすべては、これらのいずれかです。
| 型 | 例 | 説明 |
|---|---|---|
| String (文字列) | "Hello, world!" |
Unicode文字のシーケンスで、必ずダブルクォートで囲みます。 |
| Number (数値) | 42, -3.14, 2.99e8 |
整数または浮動小数点数。NaNやInfinityはありません。 |
| Boolean (真偽値) | true, false |
trueとfalseの論理値。必ず小文字です。 |
| Null | null |
意図的に値が存在しないことを表します。必ず小文字です。 |
| Array (配列) | [1, "two", false] |
順序付けられた値のリスト。角括弧[]で囲みます。 |
| Object (オブジェクト) | {"key": "value"} |
順序付けられていないキーと値のペアのコレクション。波括弧{}で囲みます。 |
これだけです。日付も、関数も、特殊な型もありません。このシンプルさはバグではなく仕様(フィーチャー)であり、データが事実上あらゆるプログラミング言語で理解できることを保証します。
構造:オブジェクトと配列
本当の魔法は、これらの基本要素を組み合わせたときに起こります。
オブジェクトは、名前のついたもののコレクションがあるときに使います。「キー」(名前)はダブルクォートで囲まれた文字列でなければなりません。「値」は、他のオブジェクトや配列を含む6つのデータ型のいずれかになります。これで階層構造を作ります。
配列は、順序のあるもののリストがあるときに使います。順序が重要で、ゼロから始まる位置(インデックス)でアイテムにアクセスします。
簡単なユーザープロファイルを作ってみましょう。これはnameやemailのような名前付きのプロパティを持っているので、オブジェクトです。そのプロパティの一つ、skillsはリストなので、配列を使います。
{
"userId": "u-9a8b7c",
"username": "CodeWizard",
"isActive": true,
"lastLogin": null,
"profile": {
"realName": "Dana Scully",
"location": "Washington, D.C."
},
"skills": [
"Forensic Pathology",
"Firearms",
"Rational Skepticism"
]
}
ネスト構造がわかりますか?オブジェクト(profile)がメインオブジェクト内の値になっています。配列(skills)もまた別の値です。このツリーのような構造は必要なだけ深くすることができ、信じられないほど複雑なデータもモデル化できます。
JavaScriptでは、このデータへのアクセスが驚くほど直感的です:
data.username は "CodeWizard" を返します。
data.profile.realName は "Dana Scully" を返します。
data.skills[0] は "Forensic Pathology" を返します。
このようにネイティブの言語構造に直接マッピングできる点こそ、開発者がJSONを愛してやまない理由です。
守るべき交通ルール:構文編
有効なJSONであるためには、いくつかの厳格なルールに従う必要があります。この厳格さこそが、機械による解析を非常に信頼性の高いものにしています。
- ダブルクォートのみ: すべてのキーとすべての文字列の値は、必ずダブルクォート (
") で囲む必要があります。シングルクォート (') は構文エラーになります。 - 末尾のカンマはNG: カンマは配列の要素やオブジェクトのペアを区切るために使われます。最後のアイテムの後にカンマを置くことはできません。
// ダメな例! `true` の後に余計なカンマがある { "key1": "value1", "key2": true, } - オブジェクトと配列: データはオブジェクト (
{}) または配列 ([]) で構造化されます。有効なJSONドキュメントは単一の値(文字列"hello"など)でもあり得ますが、トップレベルのコンテナとしてオブジェクトか配列が使われるのがほとんどです。 - 空白は自由: 文字列の外にあるスペース、タブ、改行は意味を持ちません。これにより、人間が読むための「pretty(きれい)」なインデント形式と、効率的なネットワーク転送のための「minified(最小化)」された1行形式の両方が可能になります。
実世界でのストーリー
ソーシャルメディアのフィード
フロントエンド開発者のマヤは、新しいソーシャルネットワークの無限スクロールフィードを構築するタスクを任されました。ユーザーが一番下までスクロールするたびに、彼女のJavaScriptコードはサーバーにもっと投稿を要求する必要があります。サーバーはHTMLではなく、純粋なデータで応答します。それはJSONの配列で送られてきて、各アイテムは投稿を表すオブジェクトです。このオブジェクトには、投稿のテキスト、作者のユーザー名、プロフィール写真へのリンク、いいねの数、さらには最初の数件のコメントのネストされた配列まで含まれています。マヤのコードはこのクリーンなJSONを受け取り、配列をループ処理して、各投稿のHTMLを動的に作成し、ページに追加していきます。
ここでの教訓: JSONは現代の動的なWebアプリケーションの生命線であり、サーバーの頭脳とブラウザの表示の間の軽量なメッセンジャーとして機能します。
ゲームの設定ファイル
インディーゲーム開発者のレオは、ロールプレイングゲームを制作中です。彼は何百ものアイテム(剣、ポーション、鎧など)を管理する必要があります。各アイテムのプロパティ(名前、ダメージ、重さ、価格)をゲームのC++コードに直接ハードコーディングするのは、バランス調整や更新をするのが悪夢になるでしょう。代わりに、彼はitems.jsonファイルを作成します。これは巨大なJSONオブジェクトで、各キーがアイテムID("longsword"など)で、その値がすべてのステータスを含む別のオブジェクトになっています。ゲームが開始されると、このファイルを読み込み、すべてのアイテムデータをメモリにロードします。ゲームのバランスを再調整するには、このテキストファイルを編集するだけでよく、再コンパイルは必要ありません。
ここでの教訓: JSONは設定ファイルとして優れたフォーマットであり、アプリケーションのデータとそのロジックを分離し、人間が簡単に編集できるようにします。
マイクロサービスのオーケストラ
バックエンドエンジニアのファティマは、数十のマイクロサービスで構成されるシステムに取り組んでいます。「ユーザーサービス」はユーザーアカウントを管理し、「注文サービス」は購入を管理し、「通知サービス」はメールを送信します。ユーザーが注文をすると、注文サービスはユーザーの配送先住所を確認する必要があります。データベースを直接クエリするのではなく、GET /api/users/123/addressのようなユーザーサービスのAPIエンドポイントにHTTPリクエストを送ります。ユーザーサービスは{"street": "123 Main St", "city": "Anytown"}のようなシンプルなJSONオブジェクトで応答します。注文サービスはこれをパースして注文を検証し、次に通知サービスに(これもJSONペイロードで)リクエストを送信して領収書をメールで送るよう依頼します。
ここでの教訓: 分散システムにおいて、JSONは言語に依存しない普遍的な契約書として機能し、Go、Python、Node.jsで書かれたサービス同士がシームレスに通信することを可能にします。
よくある間違いと落とし穴
- 末尾のカンマ: これは最もよくあるバリデーションエラーです。JavaScriptの配列やオブジェクトはもっと寛容なことが多いですが、JSONは厳格です。コレクションの最後の要素の後にカンマを置いてはいけません。
- コメント: JSONにコメントはありません。以上。
//や/* */に慣れている開発者はつい追加しがちですが、それは即座に無効なJSONとなります。「公式」なハックとしては、"_comment": "ここにメモ"のようなキーを追加することです。パーサーはこれを単なる別のデータとして扱います。 - シングルクォート vs ダブルクォート: すべてのキーとすべての文字列は必ずダブルクォート (
") を使う必要があります。Pythonの辞書や一部のJavaScriptのスタイルガイドから来た人はシングルクォートに慣れているかもしれませんが、JSONでは禁止されています。 undefinedなんてものは無い: JavaScriptでは、存在しないオブジェクトのプロパティはundefinedです。JSONにはこの概念がありません。存在しない、あるいは空の値を表現するには、明示的にnullを使わなければなりません。- エスケープされていないクォート: 文字列の値にダブルクォートを含めたい場合は、バックスラッシュ (
\) でエスケープする必要があります。これを忘れると({"quote": "She said "Hello""})、構造が壊れてしまいます。正しい方法は{"quote": "She said \"Hello\""}です。
なぜ注目すべきなのか
現代のソフトウェア開発において、JSONはもはや「レーダーに映る」どころか、レーダーそのものなのです。非常に多くの重要なタスクでデフォルトのフォーマットとなっているため、JSONを知らないのは、塩を知らないシェフのようなものです。
次のようなときはいつでもJSONを思い浮かべるべきです:
- Web APIを構築または利用するとき。
- アプリケーションの設定ファイルが必要なとき。
- 構造化データをシンプルなテキストファイルやMongoDBのようなNoSQLデータベースに保存する必要があるとき。
- サーバーサイドのプロセスからクライアントサイドのJavaScriptアプリケーションにデータを送信するとき。
- ネットワーク経由で送信したりディスクに保存したりするために、オブジェクトをシリアライズするためのシンプルで人間が読めるフォーマットが必要なとき。
要するに、2つの異なるプログラムに会話をさせたいとき、あるいはデータとコードを分離したいとき、JSONはほぼ常に、あなたの最初にして最良の答えとなるでしょう。
もっと深掘りする
- JSON.org: ダグラス・クロックフォードによるオリジナルの1ページ仕様書。簡潔なドキュメントの傑作です。(日本語版へのリンクを修正)
- RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format: 公式で正式なインターネット標準。内容は濃いですが、決定版です。
- MDN Web Docs: JSON: Web開発者向けの優れた実践的ガイド。JavaScript組み込みの
JSONオブジェクトに焦点を当てています。 - Wikipedia: JSON: その歴史、代替技術、プログラミングの世界における役割について、大まかに概観したい場合に。
- Google TechTalks: The JSON Saga: ダグラス・クロックフォード自身がJSONの歴史と設計思想を説明している動画。楽しくて洞察に満ちた一本です。