JavaScript Object Notation

JavaScript Object Notationはデータ記述言語の1つである。軽量なテキストベースのデータ交換用フォーマットでありプログラミング言語を問わず利用できる。名称と構文はJavaScriptにおけるオブジェクトの表記法に由来する。

1. 特徴
-----

JSONはウェブブラウザなどでよく使われているECMA-262, revision 3準拠のJavaScript  をベースとしている。2006年7月にRFC 4627で仕様が規定され、その後、何度か改定され、2017年12月14日にIETF STD 90およびRFC 8259およびECMA-404 2nd editionが発表された。MIMEタイプは application/json、拡張子はjsonとされた。

IETFおよびECMAおよびISOの仕様の改定の歴史

2006年7月 - RFC 4627
2013年3月 - RFC 7158
2013年10月 - [1]
2014年3月 - RFC 7159
2017年11月30日 - [2]
2017年12月14日 - RFC 8259 および [3] および [4]JSONはJavaScriptにおけるオブジェクト表記法のサブセットであるが、JavaScriptでの利用に限られたものではない。

JSONは単純であるので、特にAjaxの分野で利用が広がりつつある。JavaScriptでJSONをパースして読み込むには、文字列をJavaScriptのコードとして解釈させる eval 関数を作用させるだけでよい。このように、広く普及しているウェブブラウザ搭載言語であるJavaScriptで簡単に読み込めるため、Ajaxの開発者達から注目を浴びることになった。

JavaScript言語以外でも、ほとんどの言語においてJSONは単純な処理で書き出しや読み込みができる。そのため、JSONは異なるプログラミング言語の間でのデータの受渡しには能率的である。ウェブアプリケーションの場合において、ウェブクライアントでのJavaScriptとのデータの受渡しなどはその最たる活用例と言える。プロセス間通信、マシン間通信においても、疎結合にするため、JSONで情報を受け渡しすることもある。

1.1. JSONの発見
------------

ダグラス・クロックフォードはJavaScriptのプログラマで、JSONを広めた一人だが、「The JSON Saga」と題したプレゼンテーション中で「自分はJSONと名付けたが、考案者ではなく、それ自体は“自然に”存在していたもので、早い例としては1996年にはNetscape Navigatorでデータ交換用に使われていた。だから“発見した”ということになるのだが、発見したのも自分が最初ではない」といったように述べている。以上のことを縮めて「JavaScriptのオブジェクト表記法からJSONが発見された。」と表現されている場合がある。

2. 表記方法
-------

JSONで表現するデータ型は以下の通りで、これらを組み合わせてデータを記述する。true, false, null などは全て小文字でなくてはならない。

オブジェクト
配列
数値
文字列
真偽値
null数値は10進法表記に限り、8進、16進法表記などはできない。また浮動小数点数としては 1.0e-10 といった指数表記もできる。

文字列はUnicode文字列である。基本的にはJavaScriptの文字列リテラルと同様だが、囲むのにシングルクォートは使えない。バックスラッシュによるエスケープがある。

配列はゼロ個以上の値をコンマで区切って、角かっこでくくることで表現する。例えば以下のように表現する：["milk", "bread", "eggs"]

オブジェクトはキーと値のペアをコロンで対にして、これらの対をコンマで区切ってゼロ個以上列挙し、全体を波かっこでくくることで表現する。例えば以下のように表現する：{"name": "John Smith", "age": 33}

ここで注意することはキーとして使うデータ型は文字列に限ることである。したがって、{name: "John Smith", age: 33}

という表記は許されない。この後者の表記はJavaScriptのオブジェクトの表記法としては正しいが、JSONとしては不正な表記である。

プログラム上で生成した文字列をJSONとして扱う場合、ダブルクォーテーション"を含む文字列を利用しなければいけないことに注意が必要である。なぜならコード上の"は文字列定義に利用される"であり、生成されるのはあくまで文字列helloであって文字列"hello"ではない。JSONの文字列型は後者であると定義されているので、以下のようにエラーを発生させる。利用時にはJSON生成関数を利用する方がより安全である。 const invalidJSON = "hello"; const validJSON = '"hello"';

JSON.parse // Thrown: // SyntaxError: Unexpected token h in JSON at position 0 JSON.parse // 'hello'

// safe JSON generation const output = JSON.stringify output // '"hello"'<WtXmlEndTag />

2.1. エンコーディング
-------------

RFC 8259より、閉じられたエコシステムで利用する場合を除き、文字コードはUTF-8でエンコードすることが必須  となっている。ネットワークでJSONを送信する場合は、バイト順マークを先頭に付加してはいけない 。

過去のIETFの仕様では、JSONテキストはUnicodeでエンコードするとされていた 。デフォルトのエンコーディングはUTF-8であった。なお、単独の文字列でない限り最初の2文字は必ずASCII文字であるので、最初の4バイトを見ることにより、UTF-8、UTF-16LE、UTF-16BE、UTF-32LE、UTF-32BEのいずれの形式でエンコードされているか判別できた。

3. AjaxにおけるJSONの利用
------------------

AjaxにおいてXMLHttpRequestで非同期にJSONでのデータを受け取る例を示す：

3.1. 古典的な例
----------

var the_object; var http_request = new XMLHttpRequest; http_request.open; http_request.onreadystatechange = function  { if  { if  { the_object = eval" ); } else { alert; } http_request = null; } }; http_request.send;

3.2. 新しい記法を利用した例
----------------

var the_object; var http_request = new XMLHttpRequest; http_request.open; http_request.responseType = "json"; http_request.addEventListener  { if  { the_object = http_request.response; } else { alert; } delete http_request; }); http_request.send;

ここでいずれも、http_request はXMLHttpRequestオブジェクトであり、それを url にアクセスして返ってきたJSONで記述されたデータを the_object に格納される。いま、XMLHttpRequestを用いて実装をしたが、iframeなどの他の実装方法もある。また、JavaScriptライブラリのprototype.jsではHTTPの X-JSON ヘッダを利用して簡単にJSONデータの受渡しができる。

4. ライブラリ
--------

JSONは多くのプログラミング言語で利用可能なライブラリーなどが提供されている。例えば、ActionScript, C, C++, C#, ColdFusion, Common Lisp, Curl, D, Delphi, E, Elixir, Erlang, Groovy, Haskell, Java, JavaScript , Lisp, Lua, ML, Objective-C, Objective CAML, Perl, PHP, Python, R, Rebol, Ruby, Scala, Squeakなど。

ただし、テキストファイル、データを交換する手段を持つプログラミング言語であれば自力でパースして入力したり、フォーマット処理で出力は可能である。

5. JSONPath
-----------

JSONPath は JSON のクエリ式で、JSON の一部分を示すことが出来る。XML の XPath に対応するものとして Stefan Gössner が2007年に提案した。現在 IETF にて仕様が作成中である。様々なプログラミング言語でライブラリが実装されている。データベースでは、Oracle Database、Microsoft SQL Server、MySQL、PostgreSQL、MongoDB、RedisJSONなど広く採用されている。

例として、下記 JSON に対する、$.users[0:2].name の結果は ["Foo", "Bar"] になる。 { "users": [ {"name": "Foo"}, {"name": "Bar"}, {"name": "Baz"} ] }

6. 改行区切りのJSON
-------------

1行を1つのJSONとする改行区切りのJSONが複数の人によって提案されている。仕様は同一である。改行コードは

を使わなければならないが、JSON の末尾に \r があっても無視されることから \r も利用可能である。
JSON Lines  - 拡張子は jsonl
Newline delimited JSON - 拡張子は ndjson 、MIMEタイプは application/x-ndjsonComma-Separated Values よりも柔軟性がある。また、JSONの配列を使うよりも可読性があるうえ、ストリーミングにすることができる。以下は例。 {"ts":"2020-06-18T10:44:12","started":{"pid":45678}} {"ts":"2020-06-18T10:44:13","logged_in":{"username":"foo"},"connection":{"addr":"1.2.3.4","port":5678}} {"ts":"2020-06-18T10:44:15","registered":{"username":"bar","email":"bar@example.com"},"connection":{"addr":"2.3.4.5","port":6789}} {"ts":"2020-06-18T10:44:16","logged_out":{"username":"foo"},"connection":{"addr":"1.2.3.4","port":5678}}

7. JSON5
--------

ECMAScript 5.1 に基づき、人間にとってより読み書きしやすい JSON5 が提案されている。コメントを書けたり、オブジェクトのキーは " が不要だったり、末尾カンマを付けられたりする。拡張子は json5 、MIMEタイプは application/json5 。 // コメント {a: 1,}

8. 他のデータ記述法との関係
---------------

XMLJSONはXMLと違ってマークアップ言語ではない。ウェブブラウザから利用できるという点では共通している。また両者とも巨大なバイナリデータを扱う仕組みがないことが共通している。YAMLJSONはYAMLのサブセットと見なしてよい。YAMLにはブロック形式とインライン形式の表記法があるが、JSONは後者にさらに制約を加えたものと捉えることができる。例えばRubyでは以下のようにしてJSONをYAMLとして読み込むことができる：the_object = YAML.loadYAML 1.1以前は、配列と連想配列の区切りをそれぞれ , のようにカンマ+スペースの形にすることでJSONのスーパーセットとなったが、YAML 1.2では区切り文字も互換となったため、正常なJSON文書においては公式に完全なスーパーセットとなった。僅かな相違点として、連想配列のキーがユニークであるべきことをJSONではSHOULDレベルで要請するのに対し、YAML 1.2ではMUSTレベルで要請している為、該当する異常データのエラーハンドリングに違いが出る可能性はある。

9. 出典
-----

10. 関連項目
--------

Ajax
JSONP
JSON Schema
JSON-RPC
JSON Web Token
Jaql
MooTools
コンピュータ言語

11. 外部リンク
---------

[5]
[6]
IETFの仕様書
[7] および RFC 8259
古い廃止された仕様書
RFC 4627
RFC 7158
RFC 7159
[8]
[9]