JSONでnull値を返すための推奨される方法は何ですか?プリミティブには別の好みがありますか?
たとえば、サーバー上の私のオブジェクトに値がない "myCount"という整数がある場合、その値に対する最も正しいJSONは次のようになります。
{}
または
{
"myCount": null
}
または
{
"myCount": 0
}
文字列についても同じ質問です。サーバーにnull文字列 "myString"がある場合、それが最良のJSONです。
{}
または
{
"myString": null
}
または
{
"myString": ""
}
または(主が私を助けて)
{
"myString": "null"
}
私は、コレクションがJSON内で空のコレクションとして表現されることを好む http://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html
空の配列は次のように表現されます。
{
"myArray": []
}
編集サマリー
「個人的な好み」の議論は現実的に見えますが、コミュニティとして私たちはこれまで以上に多くの異種のサービス/情報源を消費することになるという点で近視眼的です。 JSON構造のための規約は、前記サービスの消費と再利用を正常化するのに役立ちます。標準を確立することに関して、私はいくつかの例外を除いてジャクソン条約の大部分を採用することを提案するでしょう:
ほとんどnull値を持つJSONオブジェクトを返す場合は、複数のサービスにリファクタリングする候補があるかもしれません。
{
"value1": null,
"value2": null,
"text1": null,
"text2": "hello",
"intValue": 0, //use primitive only if you are absolutely sure the answer is 0
"myList": [],
"myEmptyList": null, //NOT BEST PRACTICE - return [] instead
"boolean1": null, //use primitive only if you are absolutely sure the answer is true/false
"littleboolean": false
}
上記のJSONは、以下のJavaクラスから生成されました。
package jackson;
import Java.util.ArrayList;
import Java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonApp {
public static class Data {
public Integer value1;
public Integer value2;
public String text1;
public String text2 = "hello";
public int intValue;
public List<Object> myList = new ArrayList<Object>();
public List<Object> myEmptyList;
public Boolean boolean1;
public boolean littleboolean;
}
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(new Data()));
}
}
Mavenの依存関係:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.0</version>
</dependency>
それぞれの構文解析を評価しましょう。
http://jsfiddle.net/brandonscript/Y2dGv/
var json1 = '{}';
var json2 = '{"myCount": null}';
var json3 = '{"myCount": 0}';
var json4 = '{"myString": ""}';
var json5 = '{"myString": "null"}';
var json6 = '{"myArray": []}';
console.log(JSON.parse(json1)); // {}
console.log(JSON.parse(json2)); // {myCount: null}
console.log(JSON.parse(json3)); // {myCount: 0}
console.log(JSON.parse(json4)); // {myString: ""}
console.log(JSON.parse(json5)); // {myString: "null"}
console.log(JSON.parse(json6)); // {myArray: []}
tl; dr ここ:
json2変数の中のフラグメントは、 JSON仕様 が
null
を表す必要があることを示す方法です。しかしいつものように、それはあなたがしていることに依存します - 時々それをするための「正しい」方法はあなたの状況のためにいつもうまくいかない。あなたの判断を使い、十分な情報に基づいた決断を下してください。
JSON1 {}
これは空のオブジェクトを返します。そこにデータはありません、そしてそれがあなたが探しているどんなキー(それがmyCount
であろうと何か他のものであろうと)がなんであれundefined
であることをあなたに告げることになるだけです。
JSON2 {"myCount": null}
この場合、myCount
は実際に定義されていますが、その値はnull
ですが。これはnotが "not undefined
とnot null
"の両方と同じであり、どちらかの条件でテストしている場合、これは成功するかもしれませんがJSON1は失敗します。
これは、 _ JSON仕様 に従ってnull
を表すための最も確実な方法です。
JSON3 {"myCount": 0}
この場合、myCountは0です。これはnull
と同じではなく、false
と同じではありません。あなたの条件付きステートメントがmyCount > 0
を評価するならば、これは持っている価値があるかもしれません。さらに、この値に基づいて計算を実行している場合は、0が便利です。 null
をテストしようとしているのであれば、実際にはまったく機能しません。
JSON4 {"myString": ""}
この場合、あなたは空の文字列を得ています。これもまた、JSON2と同様に定義されていますが、空です。 if (obj.myString == "")
をテストすることはできましたが、null
またはundefined
をテストすることはできませんでした。
JSON5 {"myString": "null"}
stringの値をnullに設定しているので、これはおそらくあなたを困惑させるでしょう。この場合、obj.myString == "null"
はnot== null
です。
JSON6 {"myArray": []}
これはあなたの配列myArray
が存在することを教えてくれますが、それは空です。これはmyArray
に対してカウントや評価を実行しようとしている場合に便利です。たとえば、ユーザーが投稿した写真の数を評価するとします。myArray.length
を実行すると、0
:definedが返されますが、投稿された写真はありません。
null
を表す方法は1つしかありません。それはnull
です。
console.log(null === null); // true
console.log(null === true); // false
console.log(null === false); // false
console.log(null === 'null'); // false
console.log(null === "null"); // false
console.log(null === ""); // false
console.log(null === []); // false
console.log(null === 0); // false
それは言うことです。 JSON表現を使用するクライアントのいずれかが===
演算子を使用する場合。それは彼らにとって問題となる可能性があります。
もしあなたがその属性myCount
が値を持たないオブジェクトを持っていることを伝えたいなら:
{ "myCount": null }
もしあなたが属性を持たないオブジェクトを持っていることをあなたが伝えようとしたら:
{}
クライアントコードはmyCount
にアクセスしてundefined
を取得しようとします。それはありません。
空のリストであるmyCount
という属性を持つオブジェクトがあると伝えたとしたら、どうなりますか。
{ "myCount": [] }
その特定のキーには値がないことを示すためにnull
を使用します。例えば、「あなたの家庭にある機器の数がインターネットに接続すること」が不明であることを表すためにnull
を使用します。
一方、その特定のキーが適用できない場合は{}
を使用してください。たとえば、たとえnull
が「インターネットに接続されている車の数」という質問に数えても、車を所有していない人には表示されません。
デフォルトが意味を成さない限り、デフォルト値をデフォルトにしないようにします。無価値を表すためにnull
を使用することにしたとしても、絶対に"null"
を使用しないでください。
変数のデータ型として "default"(文字列/オブジェクトの場合はnull
、数値の場合は0
)を選択しますが、実際にオブジェクトを消費するコードにはどのコードが必要かを確認します。 null
/defaultと "not present"の間に時々区別があることを忘れないでください。
nullオブジェクトパターンをチェックアウトする - null
の代わりに特別なオブジェクトを渡すほうが良い場合があります(すなわち、配列の場合はnull
の代わりに[]
配列、文字列の場合は""
)。
これは個人的な状況による選択です。覚えておくべき重要なことは、空の文字列と数字のゼロがnull
と概念的に異なるということです。
count
の場合はおそらく何らかの有効な数値が欲しいでしょう(count
が未知であるか未定義でない限り)が、文字列の場合は誰が知っていますか?空の文字列はあなたのアプリケーションで mean 何かになる可能性があります。それともそうではありません。決めるのはあなた次第です。
JSON仕様 によると、最も外側のコンテナーは、上記のコメントの大部分で暗示されているように辞書(または 'オブジェクト')である必要はありません。それはまた、リストまたは裸の値(すなわち、文字列、数値、ブール値、またはヌル)でもよい。 JSONでNULL値を表したい場合は、JSONストリング全体(JSONストリングを含む引用符を除く)は単純にnull
です。中括弧、大括弧、引用符はありません。 null値を持つキーを含む辞書({"key1":null}
)、またはnull値を持つリスト([null]
)を指定できますが、これらはそれ自体null値ではありません - これらは適切な辞書およびリストです。同様に、空の辞書({}
)または空のリスト([]
)は完全に問題ありませんが、nullでもありません。
Pythonでは:
>>> print json.loads('{"key1":null}')
{u'key1': None}
>>> print json.loads('[null]')
[None]
>>> print json.loads('[]')
[]
>>> print json.loads('{}')
{}
>>> print json.loads('null')
None