What is the preferred method for returning null values in JSON? Is there a different preference for primitives?
For example, if my object on the server has an Integer called "myCount" with no value, the most correct JSON for that value would be:
{}
or
{ "myCount": null }
or
{ "myCount": 0 }
Same question for Strings - if I have a null string "myString" on the server, is the best JSON:
{}
or
{ "myString": null }
or
{ "myString": "" }
or (lord help me)
{ "myString": "null" }
I like the convention for collections to be represented in the JSON as an empty collection http://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html
An empty Array would be represented:
{ "myArray": [] }
EDIT Summary
The 'personal preference' argument seems realistic, but short sighted in that, as a community we will be consuming an ever greater number of disparate services/sources. Conventions for JSON structure would help normalize consumption and reuse of said services. As far as establishing a standard, I would suggest adopting most of the Jackson conventions with a few exceptions:
If you are returning a JSON object with mostly null values, you may have a candidate for refactoring into multiple services.
{ "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 }
The above JSON was generated from the following Java class.
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:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.3.0</version> </dependency>
If you want to represent a null value in JSON, the entire JSON string (excluding the quotes containing the JSON string) is simply null . No braces, no brackets, no quotes.
JSON has a special value called null which can be set on any type of data including arrays, objects, number and boolean types.
You should definitely include it if there is any need to distinguish between null and undefined since those have two different meanings in Javascript. You can think of null as meaning the property is unknown or meaningless, and undefined as meaning the property doesn't exist.
Strings, Booleans and integers do not have an 'empty' form, so there it is okay to use null values.
Let's evaluate the parsing of each:
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: []}
The tl;dr here:
The fragment in the json2 variable is the way the JSON spec indicates
null
should be represented. But as always, it depends on what you're doing -- sometimes the "right" way to do it doesn't always work for your situation. Use your judgement and make an informed decision.
JSON1 {}
This returns an empty object. There is no data there, and it's only going to tell you that whatever key you're looking for (be it myCount
or something else) is of type undefined
.
JSON2 {"myCount": null}
In this case, myCount
is actually defined, albeit its value is null
. This is not the same as both "not undefined
and not null
", and if you were testing for one condition or the other, this might succeed whereas JSON1 would fail.
This is the definitive way to represent null
per the JSON spec.
JSON3 {"myCount": 0}
In this case, myCount is 0. That's not the same as null
, and it's not the same as false
. If your conditional statement evaluates myCount > 0
, then this might be worthwhile to have. Moreover, if you're running calculations based on the value here, 0 could be useful. If you're trying to test for null
however, this is actually not going to work at all.
JSON4 {"myString": ""}
In this case, you're getting an empty string. Again, as with JSON2, it's defined, but it's empty. You could test for if (obj.myString == "")
but you could not test for null
or undefined
.
JSON5 {"myString": "null"}
This is probably going to get you in trouble, because you're setting the string value to null; in this case, obj.myString == "null"
however it is not == null
.
JSON6 {"myArray": []}
This will tell you that your array myArray
exists, but it's empty. This is useful if you're trying to perform a count or evaluation on myArray
. For instance, say you wanted to evaluate the number of photos a user posted - you could do myArray.length
and it would return 0
: defined, but no photos posted.
null
is not zero. It is not a value, per se: it is a value outside the domain of the variable indicating missing or unknown data.
There is only one way to represent null
in JSON. Per the specs (RFC 4627 and json.org):
2.1. Values A JSON value MUST be an object, array, number, or string, or one of the following three literal names: false null true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With