JSON ちょっとだけ入門

> - この記事は、標準化などに知見のある人を想定読者としています。
> - ちょっとした JSON入門の導入部のみ提示しており、その後 JSON標準を直接見ていけるようなきっかけになれば望ましいという位置付けです。

# JSON とは

JSON はデータ形式のひとつです。
類似のものに XML がありますが、多くの人が JSON は XML よりも人間が直接読み書きするのに向いていると考えるようです。
JSONの出自は JavaScript ですが、いまでは様々なアプリケーションや (JavaScript以外の) 言語処理系で多く利用される重要なデータ形式です。

## JSONの歴史

JSON は 21世紀のインターネット普及に合わせるが如く登場そして普及してきました。
この歴史的な経緯は、[Publickey: 事実上最後のJSON仕様「RFC 8259」と「ECMA-404 2nd Editon」公開。UTF-8エンコード必須に](https://www.publickey1.jp/blog/17/jsonrfc_8259ecma-404_2nd_editonutf-8.html) に非常に詳しくそして正確に記述があり必見と思いました。

## 関連する標準化仕様

JSON が関連する標準化仕様には、以下のようなものがあります。

* IETF: [RFC 8259](https://www.rfc-editor.org/rfc/rfc8259.html)
* ECMA: [ECMA-404](https://www.ecma-international.org/publications-and-standards/standards/ecma-404/)

JSON がどのような仕様なのかを「正確に」理解するには、上記の標準化仕様を直接確認するのが確実です。JSONはこの手の標準化仕様としては「小さい」仕様であり、比較的読み下しやすい仕様だと思いました。

## JSON仕様おおまかピックアップ

> - 雑に JSON 仕様を説明します。
> - 正確な仕様は標準化仕様を参照ください。そちらが確実で安全です。
> - ここではおおざっぱな説明を、かなり意訳しながら、しかもちょっとだけ説明します。

### JSONサンプル (RFC 8259 から引用)

まずは JSON がどのような形式になるのかを、RFC 8259 から見てみましょう。
おおよそ、`"キー"` `:` `値` の形になっていて、それが `,` で区切られています。ちょっと混乱しそうなのは {} と [] あたりですね。前者はオブジェクト、後者は配列にあたります。

```json
{
  "Image": {
    "Width": 800,
    "Height": 600,
    "Title": "View from 15th Floor",
    "Thumbnail": {
      "Url": "http://www.example.com/image/481989943",
      "Height": 125,
      "Width": 100
    },
    "Animated": false,
    "IDs": [116, 943, 234, 38793]
  }
}
```

### JSONテキスト

このように、JSON は `UTF-8` テキストで構成され、以下のような文字によるトークンにて成り立ちます。

- ホワイトスペース(空白、水平タブ、復帰、改行)
- 6つの構造文字（[{]};,）
- 文字列、数値、3つのリテラル名(false、null、true)

### オブジェクト

私がよく見かける大抵の JSON はオブジェクトから開始されます。`{オブジェクト}` のように中括弧で囲み、1つ以上のメンバーを含みます。メンバーは以下のようになります。

- `"名前"` `:` `数値`
- `"名前"` `:` `"文字列"`
- `"名前"` `:` `{オブジェクト}`
- `"名前"` `:` `[配列]`

> - ちなみに私は JSONを初めて読み書きしようとしたときに、オブジェクトや配列が `"名前"` の右辺にくるところあたりでつまづきました。

最もシンプルなのは、`名前` `:` 値、を `,` 区切りで複数内包するオブジェクトです。

```json
{
  "Url": "http://www.example.com/image/481989943",
  "Height": 125,
  "Width": 100
}
```

### ホワイトスペース

ホワイトスペース(空白、水平タブ、復帰、改行)は存在してもしなくても内容に影響を与えないので、以下のように折り畳んで1行で表現したとしてもオブジェクトとして同じ内容です。

```json
{ "Url": "http://www.example.com/image/481989943", "Height": 125, "Width": 100 }
```

> - ちなみに `""`で囲まれた部分はホワイトスペースではなくて文字列です。この中の空白などは内容に影響があります。

### 配列

`[配列]` のように角括弧で囲み、複数の値は `,` で区切ります。0個以上の値を保持します。

```json
"IDs": [116, 943, 234, 38793]
```

値にはオブジェクトも含まれるので、以下の JSON 例(RFC 8259から引用)のように複数のオブジェクトを内包する配列も表現されます。

```json
[
  {
    "precision": "zip",
    "Latitude": 37.7668,
    "Longitude": -122.3959,
    "Address": "",
    "City": "SAN FRANCISCO",
    "State": "CA",
    "Zip": "94107",
    "Country": "US"
  },
  {
    "precision": "zip",
    "Latitude": 37.371991,
    "Longitude": -122.02602,
    "Address": "",
    "City": "SUNNYVALE",
    "State": "CA",
    "Zip": "94085",
    "Country": "US"
  }
]
```

> - 配列がオブジェクトを内包したり、オブジェクトが配列を内包したりする場合がありますが、ここを理解すると JSON が一気に身近なものに感じられることでしょう。

### 数値

`123`、`-45.67`、exp表現、のように記述します。

### 文字列

`"文字列"` のようにクオーテーションで囲まれます。
文字列エスケープには以下が該当します。詳しくはJSON仕様の標準を確認することを推奨します。

```
              %x22 /          ; "    quotation mark  U+0022
              %x5C /          ; \    reverse solidus U+005C
              %x2F /          ; /    solidus         U+002F
              %x62 /          ; b    backspace       U+0008
              %x66 /          ; f    form feed       U+000C
              %x6E /          ; n    line feed       U+000A
              %x72 /          ; r    carriage return U+000D
              %x74 /          ; t    tab             U+0009
              %x75 4HEXDIG )  ; uXXXX                U+XXXX
```

# JSONを読み書きするために

## ユーザによる操作のために

お使いの端末がパソコンであれば vscode のようなエディタツールを利用することが JSON読み書きの利便性向上に繋がります。大抵のJSON編集機能にはフォーマッターが付いており、JSONをホワイトスペースを利用して可読性ある形に整形してくれることでしょう。
そして、もしそのようなJSONフォーマッタが機能しない場合には、JSONの内容に誤りが含まれている可能性があり、これの検知目的においても JSON編集機能の利用は活躍することでしょう。

## プログラムからの操作のために

JSON用のさまざまなライブラリ、さまざまなジェネレータが提供されています。ご利用の言語処理系のためのライブラリやジェネレータを探して見るのはいかがでしょうか。

# その次は

以下の標準化仕様の読み下しに直接トライしてみてはいかがでしょうか。

* IETF: [RFC 8259](https://www.rfc-editor.org/rfc/rfc8259.html)
* ECMA: [ECMA-404](https://www.ecma-international.org/publications-and-standards/standards/ecma-404/)

英語が苦手という方には、Google Chrome や Edge に搭載されている翻訳機能も役立つことが期待できます。