JSONのkeyにあたるstringの覚え書き
JSON は最近のネットワークを通じたデータのやり取りでよく使われている。Web サービス以外にもゲームや設定ファイルに使われることがあるぐらい。
そんなわけでライブラリもそろってるし、お仕事でも機能の切り分けとして WebAPI 化したりする際に使った。
ただ、どうしても環境が環境でちょっとライブラリが使えず、まあそこまで複雑な仕組みにならないということで手書きで JSON を出力するコードをある時に書いた。 そのコードを用いて吐き出した JSON を、別環境で読み込ませようとしたときにエラーが起こった。
なんと別環境で使っているライブラリで読み込めないというケースが発生したのだ。
そのとき使っていたライブラリは Google GSON というライブラリ。
これは JSON を Java オブジェクトにシリアライズしたりデシリアライズしてくれるライブラリ。
不思議なことに一部はできていたが、途中からできていなかった。JSON の形がおかしいのかと疑ったが、整形はできるし JSON.org を見てもおかしな点はない。
はてさてなぜやらと思いつつ調べると、デシリアライズに失敗した部分の key が大文字から始まるという共通点があった。
{ "Hoge" : "fuga" }
みたいな感じだったのだ。これを
{ "hoge" : "fuga" }
とすると問題なく通った。
ふと調べてみると Twitter の API とかは key の文字列が小文字から始まっていた。困ったときは仕様書に帰れというわけで、そんな決まりでもあるのだろうかと思い RFC と ECMA を調べてみた。
JSON が関係する仕様書は
と思われる。上から順に
- JSONの仕様(The application/json Media Type for JavaScript Object Notation (JSON))
- JSONのやり取りの形式(The JavaScript Object Notation (JSON) Data Interchange Format)
- Ecmaの詳細(ECMAScript® 2016 Language Specification)
- JSONのやり取りの形式(The JSON Data Interchange Format)
2つ目と4つ目は同じことを言ってる通り、中身もたぶん同じ。策定文書が違うだけだと思われるが一応上げておく。Ecma は JavaScript などの親分的存在。まあそれはさておき。
とりあえず JSON の key に関する情報を集める。
まんま json.org から引用したが、このとおり。つまり string(文字列?)であれば何でもいいように書いてある。
では string の定義を見てみる。RFC4627 には以下の通り。
A string is a sequence of zero or more Unicode characters [UNICODE].
string は0文字、あるいはそれ以上の Unicode の文字の集まり。
これは Introduction での記述。別途あった Strings では以下の通り。部分抜粋。
A string begins and ends with quotation marks. All Unicode characters may be placed within the quotation marks except for the characters that must be escaped:quotation mark, reverse solidus, and the control characters (U+0000 through U+001F).
stringsの始まりと終わりはクォーテーションです。すべてのユニコードの文字が使え、エスケープを用いることでクォーテーションマークなど(具体的にはバックスラッシュや水平タブなど)の文字も使えます。
JSON.org にもっとわかりやすい図があった。つまりこういうこと
引用しなかったが、特殊な文字の表現についてなどが書かれている。
Parsers の項を見てみたが、この辺りは JSON の形式にちゃんと対応すること、実装時によってはネストの深さや文字数によっては対応できないものがあるかもしれない、程度の注意書きだけだった。
この辺りには大文字の使用の制限に関しては存在しない。気になるところというと、同項(String)の以下のくだり
The representation of strings is similar to conventions used in the C family of programming languages
strings の表現はC言語系の形式にほぼ同じ
とはいえこれがkeyに該当する変数名のコーディング規約のたぐいだと取るのは拡大解釈が過ぎる気もする。
そしてRFC7159を見て驚愕した。13項Exampleでこんなものが書いてあった
This is a JSON object:
{ "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] } }
めっちゃ大文字使ってるやん
つまり、単にGoogleGsonが対応できてないというだけの話だった