Why doesn't the "official" json checker allow top-level primitives? [duplicate] - json

I've carefully read the JSON description http://json.org/ but I'm not sure I know the answer to the simple question. What strings are the minimum possible valid JSON?
"string" is the string valid JSON?
42 is the simple number valid JSON?
true is the boolean value a valid JSON?
{} is the empty object a valid JSON?
[] is the empty array a valid JSON?

At the time of writing, JSON was solely described in RFC4627. It describes (at the start of "2") a JSON text as being a serialized object or array.
This means that only {} and [] are valid, complete JSON strings in parsers and stringifiers which adhere to that standard.
However, the introduction of ECMA-404 changes that, and the updated advice can be read here. I've also written a blog post on the issue.
To confuse the matter further however, the JSON object (e.g. JSON.parse() and JSON.stringify()) available in web browsers is standardised in ES5, and that clearly defines the acceptable JSON texts like so:
The JSON interchange format used in this specification is exactly that described by RFC 4627 with two exceptions:
The top level JSONText production of the ECMAScript JSON grammar may consist of any JSONValue rather than being restricted to being a JSONObject or a JSONArray as specified by RFC 4627.
snipped
This would mean that all JSON values (including strings, nulls and numbers) are accepted by the JSON object, even though the JSON object technically adheres to RFC 4627.
Note that you could therefore stringify a number in a conformant browser via JSON.stringify(5), which would be rejected by another parser that adheres to RFC4627, but which doesn't have the specific exception listed above. Ruby, for example, would seem to be one such example which only accepts objects and arrays as the root. PHP, on the other hand, specifically adds the exception that "it will also encode and decode scalar types and NULL".

There are at least four documents which can be considered JSON standards on the Internet. The RFCs referenced all describe the mime type application/json. Here is what each has to say about the top-level values, and whether anything other than an object or array is allowed at the top:
RFC-4627: No.
A JSON text is a sequence of tokens. The set of tokens includes six
structural characters, strings, numbers, and three literal names.
A JSON text is a serialized object or array.
JSON-text = object / array
Note that RFC-4627 was marked "informational" as opposed to "proposed standard", and that it is obsoleted by RFC-7159, which in turn is obsoleted by RFC-8259.
RFC-8259: Yes.
A JSON text is a sequence of tokens. The set of tokens includes six
structural characters, strings, numbers, and three literal names.
A JSON text is a serialized value. Note that certain previous
specifications of JSON constrained a JSON text to be an object or an
array. Implementations that generate only objects or arrays where a
JSON text is called for will be interoperable in the sense that all
implementations will accept these as conforming JSON texts.
JSON-text = ws value ws
RFC-8259 is dated December 2017 and is marked "INTERNET STANDARD".
ECMA-262: Yes.
The JSON Syntactic Grammar defines a valid JSON text in terms of tokens defined by the JSON lexical
grammar. The goal symbol of the grammar is JSONText.
Syntax
JSONText :
JSONValue
JSONValue :
JSONNullLiteral
JSONBooleanLiteral
JSONObject
JSONArray
JSONString
JSONNumber
ECMA-404: Yes.
A JSON text is a sequence of tokens formed from Unicode code points that conforms to the JSON value
grammar. The set of tokens includes six structural tokens, strings, numbers, and three literal name tokens.

According to the old definition in RFC 4627 (which was obsoleted in March 2014 by RFC 7159), those were all valid "JSON values", but only the last two would constitute a complete "JSON text":
A JSON text is a serialized object or array.
Depending on the parser used, the lone "JSON values" might be accepted anyway. For example (sticking to the "JSON value" vs "JSON text" terminology):
the JSON.parse() function now standardised in modern browsers accepts any "JSON value"
the PHP function json_decode was introduced in version 5.2.0 only accepting a whole "JSON text", but was amended to accept any "JSON value" in version 5.2.1
Python's json.loads accepts any "JSON value" according to examples on this manual page
the validator at http://jsonlint.com expects a full "JSON text"
the Ruby JSON module will only accept a full "JSON text" (at least according to the comments on this manual page)
The distinction is a bit like the distinction between an "XML document" and an "XML fragment", although technically <foo /> is a well-formed XML document (it would be better written as <?xml version="1.0" ?><foo />, but as pointed out in comments, the <?xml declaration is technically optional).

JSON stands for JavaScript Object Notation. Only {} and [] define a Javascript object. The other examples are value literals. There are object types in Javascript for working with those values, but the expression "string" is a source code representation of a literal value and not an object.
Keep in mind that JSON is not Javascript. It is a notation that represents data. It has a very simple and limited structure. JSON data is structured using {},:[] characters. You can only use literal values inside that structure.
It is perfectly valid for a server to respond with either an object description or a literal value. All JSON parsers should be handle to handle just a literal value, but only one value. JSON can only represent a single object at a time. So for a server to return more than one value it would have to structure it as an object or an array.

The ecma specification might be useful for reference:
http://www.ecma-international.org/ecma-262/5.1/
The parse function parses a JSON text (a JSON-formatted String) and produces an ECMAScript value. The
JSON format is a restricted form of ECMAScript literal. JSON objects are realized as ECMAScript objects.
JSON arrays are realized as ECMAScript arrays. JSON strings, numbers, booleans, and null are realized as
ECMAScript Strings, Numbers, Booleans, and null. JSON uses a more limited set of white space characters
than WhiteSpace and allows Unicode code points U+2028 and U+2029 to directly appear in JSONString literals
without using an escape sequence. The process of parsing is similar to 11.1.4 and 11.1.5 as constrained by
the JSON grammar.
JSON.parse("string"); // SyntaxError: Unexpected token s
JSON.parse(43); // 43
JSON.parse("43"); // 43
JSON.parse(true); // true
JSON.parse("true"); // true
JSON.parse(false);
JSON.parse("false");
JSON.parse("trueee"); // SyntaxError: Unexpected token e
JSON.parse("{}"); // {}
JSON.parse("[]"); // []

Yes, yes, yes, yes, and yes. All of them are valid JSON value literals.
However, the official RFC 4627 states:
A JSON text is a serialized object or array.
So a whole "file" should consist of an object or array as the outermost structure, which of course can be empty. Yet, many JSON parsers accept primitive values as well for input.

Just follow the railroad diagrams given on the json.org page. [] and {} are the minimum possible valid JSON objects. So the answer is [] and {}.

var x;
console.log(JSON.stringify(x)); // will output "{}"
So your answer is "{}" which denotes an empty object.

Related

is string invalid json object?

I have a question, and I can't find any doc about it.
Is string invalid object for json?
For an example, you can do this in any browser:
JS:
console.log(JSON.parse(JSON.stringify("asdf")));
Java (jackson):
ObjectMapper mapper = new ObjectMapper();
String string = mapper.writeValueAsString("asdf");
TextNode node = (TextNode)mapper.readTree(string);
System.out.println(node.getTextValue());
PHP:
echo json_decode(json_encode("asdf"));
But, as I can see, this parsers did not work with string as root object:
http://json.parser.online.fr
http://jsonparseronline.com
Also, from SWIFT documentation -
The top level object is an NSArray or NSDictionary.
According to this question, is it invalid to return json-formatted string from your controller (endpoint)?
example.com/notes/2/title
According to https://jsonlint.com, "asdf" is valid JSON. Some parsers are stricter than others. You definitely can't use it as the root for any other data though, because it's just a string, not an object or array.
Having said that, if you want an absolute definition, try reading the relevant RFC rather than documentation of a particular programming language. https://www.rfc-editor.org/rfc/rfc8259 dated Decemeber 2017 is the latest (at the time of writing this answer), as far as I know.
Specifically https://www.rfc-editor.org/rfc/rfc8259#section-2 says
A JSON text is a sequence of tokens. The set of tokens includes six
structural characters, strings, numbers, and three literal names.
A JSON text is a serialized value. Note that certain previous
specifications of JSON constrained a JSON text to be an object or an
array.
And later
Here are three small JSON texts containing only values:
"Hello world!"
42
true
So I would assume that the different parsers mentioned are implementing different versions of the spec.

Did the publication of ECMA-404 affect the validity of JSON texts such as '2' or '"hello"'?

Are the following valid JSON texts, or must their top-level value be an array or object?
4.0
"Hello World"
true
Related questions in the past, such as What is the minimum valid JSON?, and Is this simple string considered valid JSON? have concluded that they are not. This was based on the description of the JSON format in RFC-4627, which states that:
2. JSON Grammar
A JSON text is a sequence of tokens. The set of tokens includes six
structural characters, strings, numbers, and three literal names.
A JSON text is a serialized object or array.
JSON-text = object / array
These are the six structural characters:
[...]
However, the RFC-4627 status declares that it "does not specify an Internet standard of any kind". Instead, the official standard for JSON is the recently-published ECMA-404. Unlike RFC-4627, ECMA-404's description of valid JSON text does not include any requirement that it be an object or an array. For example, the section most similar to the quote above is missing that requirement:
4 JSON Text
A JSON text is a sequence of tokens formed from Unicode code points that conforms to the JSON value
grammar. The set of tokens includes six structural tokens, strings, numbers, and three literal name tokens.
The six structural tokens:
[...]
Given this new specification, are encoded non-array non-object top-level values considered valid JSON texts?
Douglas Crockford posted a comment on this Google+ post which helped me start to clarify things:
JSON is just a grammar, and the grammar includes numbers and strings. Uses of JSON must necessarily be more restrictive. RFC-4627 is one possible use, and was never intended to be the standard for JSON itself.
We cannot say that non-array non-object JSON texts are generally invalid, just that it is not valid to use them with internet media type application/json, per RFC-4627.
Representations of non-object non-array values are valid JSON texts per ECMA-404, which is the only currently published standard that might be identified as "the JSON specification".
However, it turns out that the IETF is likely to soon publish a replacement to RFC-4627 which will also be a specification of JSON. Its latest draft still includes the restriction on JSON texts, but also mentions that JSON has be specified in several places and that these specifications vary slightly. The draft specifically mentions that the definition of JSON in ECMA-262 (the ECMAScript/JavaScript specification) does not share the top-level value restriction.
Therefore, the question of whether non-object non-arrays are valid JSON texts must be disambiguated:
Is "hello" a valid JSON text as specified in RFC-4627 and its successor?
No.
Is "hello" a valid JSON text as specified by ECMA-404 and ECMA-262?
Yes.

Are JSON values valid JSON?

Are JSON values string, number, true, false, null valid JSON?
I.e., is
true
a valid JSON document? Or does is have to be an array/object?
Some validators accept this (e.g. http://jsonlint.com/), while others do not (e.g. http://jsonschemalint.com/). The RFC and json.org are not clear on this issue.
As of March 2014: Yes. From the specification:
A JSON text is a serialized value. Note that certain previous
specifications of JSON constrained a JSON text to be an object or an
array. Implementations that generate only objects or arrays where a
JSON text is called for will be interoperable in the sense that all
implementations will accept these as conforming JSON texts.
However, at the time this question was originally asked, the answer was: No. The original specification said:
A JSON text is a serialized object or array
So the outer-most data type in a JSON text had to be either an object or an array, it couldn't be a string, boolean, number or any other data type.
Yes, according to ECMA-404 The JSON Data Interchange Standard.
Source: http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
A JSON text is a sequence of tokens formed from Unicode code points that conforms to the JSON value grammar.
And following, the JSON value grammar is given as:
A JSON value can be an object, array, number, string, true, false, or null.
This directly conflicts with the RFC, as cited by #quentin. The updated RFC is 8259 which states:
Note that certain previous specifications of JSON constrained a JSON text to be an object or an array. Implementations that generate only objects or arrays where a
JSON text is called for will be interoperable in the sense that all implementations will accept these as conforming JSON texts.

Is a single string value considered valid JSON? [duplicate]

This question already has answers here:
What is the minimum valid JSON?
(8 answers)
Closed 7 years ago.
Do you consider the JSON web response:
"A serialization error occurred"
to be valid or not?
Some validators accept it while others don't.
As for new JSON RFC, json, containing only single value is pretty valid.
A JSON text is a serialized value. Note that certain previous specifications of JSON constrained a JSON text to be an object or an array.
There's a change of heart on this between RFC4627 and RFC7159:
RFC4627:
A JSON text is a serialized object or array.
JSON-text = object / array
RFC7159:
A JSON text is a serialized value. Note that certain previous
specifications of JSON constrained a JSON text to be an object or an
array. Implementations that generate only objects or arrays where a
JSON text is called for will be interoperable in the sense that all
implementations will accept these as conforming JSON texts.
JSON-text = ws value ws
No philosophical or practical justification is provided for this change of heart. The earlier version probably makes more sense as it consistently dictates that both a singe list element and a single map element (a pair or tuple) be contained. The second version allows only a single list element to be uncontained.
According to the grammar exposed in http://www.json.org/ (which references the Standard ECMA-262 3rd Edition - December 1999 par.5.1.5 The JSON Grammar) it's wrong:
The initial element must be:
and then a value can be a string:
From RFC4627:
A JSON text is a serialized object or array.
JSON-text = object / array
IE, the root element has to be an object or array, and can't be a string value by itself.
I don't care if some validator accepts it. It's wrong. It's a question of good practice, Json format must be {"key": "value", .....}. If you consider that text Json, can work, but for the rest of programmer it's not a serious Json. If you use only that text, then you don't need Json.

is "HelloWorld" a valid json response

This could be the most basic json question ever. I'm creating a WCF REST service and have a HelloWorld test function that just returns a string. I'm testing the service in fiddler and the reponse body I'm getting back is:
"HelloWorld"
I also created a function that would just return a number (double) and the response body is:
1.0
Are those valid json responses? Are simple return types just returned in plain text like that (no markup with the brackets)?
Valid JSON responses start with either a { for an object or [ for a list of objects.
Native types are not valid JSON if not encapsulated. Try JSONlint to check validity.
RFC 4672, says no. Which doesn't mean it can't work, but it isn't strictly standards compliant. (Of course, neither are all the JSON readers...)
To quote from Section 2, "JSON Grammar":
A JSON text is a sequence of tokens. The set of tokens includes six
structural characters, strings, numbers, and three literal names.
A JSON text is a serialized object or array.
JSON-text = object / array
Only objects / maps, and arrays, at the top level.
According to the official website, you need to use a syntax like this:
You need to declare what you want beetween {}, like this:
{
"test": "HelloWorld"
}
No. The following is, for example:
{
"Foo": "HelloWorld"
}
You can try JSONLint to see what validates and what does not.