このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

JSONスキーマの功罪を、印象や感情じゃなくて考えてみようか

「JSONの可能性がグンと拡がるぞ! JSONスキーマ」に対して、がくぞーさんからトラックバックをいただきました。その冒頭を引用すると:

この記事のブコメを見てみると XML Schema が在るんだし軽さがウリの JSON にそんなの必要なくね?的なコメントが散見されます。

なるほど、「なんだか複雑になりそうでヤダなー」とか「そんなもん要らねーよ」という印象や感情を持たれた方もいるんでしょうね。僕は、JSONスキーマをプロモートする気はないので、「ヤダ」とか「要らねー」の人を説得する動機はないのですが、「印象や感情だけじゃ主張や議論にはなりませんよ」って趣旨でちょっと書いてみます。

内容:

僕の感情と事情

「印象や感情じゃ、ラチあかんよ」と言いましたが、まずは僕の感情論から^^; 「JSONの可能性がグンと拡がるぞ! JSONスキーマ」にて:

読みにくい/書きにくいのは相当に痛い欠点だと思います。ローカル/インターナルに使用するなら、もう少し簡略な構文でもいいんじゃないかな、とか考えてます。

直接手で書いたり目で見たりすることを考えると、あの構文はどうにもいただけません。JSONオブジェクトにスキーマを埋め込む(自己記述的なデータを作る)ためには、JSONスキーマはJSON構文で書かなくてはならないのですが、インスタンスとスキーマが分離した状況では、(原理的には)スキーマに別構文を採用するのも許されるはずです。あの構文は、僕の感情的あるいは生理的な許容範囲を超えているので、たぶん意味的には同値な別構文をでっち上げるでしょうね、ローカル/インターナルな使用では。

まーそれはそうとして、僕の事情・状況では、「JSONスキーマは要るか/要らないか」なんて議論はナンセンスです。なぜなら、議論の余地なく「要る!」からです。実を言うと、JSONそのものではなくて、JSONライクなデータに対してスキーマ定義を必要としているのです。データ形式がJSONそのものではなく、標準に適合(コンフォーマンス)すべしの圧力も強くないので、JSON/JSONスキーマ仕様を律儀に遵守はしませんが、それでも基準(reference)としてJSONスキーマの存在は大変にありがたい、ありがたいけど構文キライ。

妥当性の検証はたいてい必要

JSONデータ、あるいはJSONライクなデータを受け取って処理するプログラムはイッパイあるでしょう。そのなかで、「入力はまったく任意だよ、どんなJSONデータでもいいよ」ってプログラムの比率は多くないと思いますよ。たいていのプログラムはデータ形式に関して何らかの仮定をしているものです。

となると、当該のプログラムにデータを渡す側、またはプログラムの入り口、ときに処理の途中でバリデーションが必要になります。「仮定しているデータ形式」が少数なら、バリデーションコードをプログラム内に撒き散らしても弊害は少ないでしょうが、データ形式=スキーマがたくさんあると、同じようなバリデーションコードを重複して書くことになり、はなはだしく無駄だし、品質も安定しません。与えられたスキーマ定義に対して、インスタンスの妥当性を検証する汎用バリデータを使ったほうがずっと楽で安心できます。

「バリデーション関数/メソッドをライブラリ化しておけばいい」とか言い出す人がいるんですが、それはトンチンカンです。スキーマ定義を必要とする状況とは、プログラミングの時点では入力のデータ形式が「確定してない/予測できない/コードでは対応できないほどに大量」とかの事情があるのです。逆に、入力(処理対象)のデータ形式が事前に確定していて少数ならば、バリデーション・ライブラリで対応可能なので、スキーマ定義や汎用バリデータは不要です。

という次第で、「JSON(あるいはJSONライク)データなんだから、スキーマやバリデーションなんて不要でしょ」って(仮に言う人がいれば)、何を根拠に言っているのか僕にはわかりません。

JSONにスキーマはそぐわない?

「スキーマだのバリデーションだのは、JSONじゃなくてXMLでやるべき」ってハナシも理解不能です(根拠があるなら、どなたか説明して)。「JSONデータを使う ならば スキーマやバリデーションは不要」という命題の待遇を取ると、「スキーマやバリデーションが必要 ならば JSONデータを使わない」となります。が、前節で述べたごとく「JSONデータなのだからスキーマやバリデーションは不要」なんてことが何で言えるのか? サッパリわからない。したがって、その待遇もワカンネー。

それに、既にJSON(またはJSONライク)データを使っている状況で、「バリデーションをより系統的にやりたい」要望が出たら、JSONからXMLへと、根本からぜーんぶ変更するんですか? 現実的じゃないけどなー。なんで労力をかけて、安直で軽いJSONを使っている状況から、面倒で重いXMLに変更しなきゃいけないの?

「JSONは安直で軽いのがとりえ」という主張は僕も大いに同意しますよ。だからこそ僕も、安直で軽い用途で使っているのです。しかし、「だから、スキーマ/バリデーションは不要、そぐわない」とか言われても必要なんだからしょうがない(しつこく言うけど)。これもまた、「だから」の前後を結ぶ推論規則が不明。「JSONを使う」ことと「スキーマ/バリデーションが必要」なことが、排他的/両立不可能である根拠があるんでしょうか。

JSONスキーマの弊害

「そんなもん要らねーよ」が、「俺には必要ない」という表明であれば、「あーそうですか」としか言いようがない。「俺には必要ない」と「私には必要です」には何の接点もなく、議論のしようがありません。では、もっと一般的に「必要ない」と言うには何を根拠とすべきでしょう。もし、JSONスキーマを必要としない人々に対して、JSONスキーマが負担や迷惑をかけるならば、「必要ない/導入すべきではない」と主張すべき理由となります。

この点に関して、JSONスキーマのインパクトはゼロではありません。若干の負担/迷惑はあります。指摘しておきます。

まず確認しておきますが、JSONスキーマは完全にオプショナルです。スキーマを使いたくない人にまでそれを強制するようなことは一切ありません。使いたくないなら使わなければいいのです。今までのスキーマなしのインスタンスが不都合になることもほぼありません。

「ほぼ」と書いたのは、次の事情です; JSONオブジェクト内にスキーマを埋め込むために、"$schema"というプロパティ名が事実上予約されました。"$ref" も参照を表す目的で予約扱いです。この状況からすると、ドル記号「$」から始まるプロパティ名はユーザーレベルでの使用は好ましくないことになります。つまり、「ドル記号からはじまるプロパティ名が自由に使えなくなる」というのが、JSONスキーマによる“弊害”です。

$schemaプロパティを含む自己記述的なJSONオブジェクトが、$schemaを知らないプログラムに渡されると変な挙動をするかもしれません。もっとも、「スキーマなんて要らない」プログラムはおそらく、制約なしの任意のデータを合理的に処理できるように出来てるはずですから平気ですよね :-) (←ジョークですから)スキーマ埋め込みJSONデータが使われるようになれば、スキーマを読まないプログラムでも、$schemaプロパティを無視するように作る必要はあるでしょう。

「ドル記号からはじまるプロパティ名」以外には、JSONスキーマが現今のJSONに影響する要素は発見できませんでした。

バリデータ実装の負担

がくぞーさんは次のように書かれています:

JavaScript だけの世界でデータ検証を行いたい時に有用なんじゃないか、と。


スキーマのパース及びデータのパース検証を考えると [檜山注:XML Schemaと比べて]JSONスキーマの方が圧倒的に軽く実装できるのではないでしょうか。

「JavaScript だけ」というわけじゃなくて、お手軽に検証を行いたい時には有用だと思います。僕はErlangで試してみたのですが、バリデータはたいした負担なしで作れます。データ型/スキーマ定義に関する仕様のなかでは、やっぱりJSONスキーマはとても軽いですね。「安直で軽い」という特徴は、データ形式だけじゃなくてスキーマに関しても貫かれているので、JSONスキーマは、ポリシーとして「反JSON的じゃなくてJSON的」だと思います。