JSON
Introduction to JSON
JSON stands for JavaScript Object Notation
and is a text format for transferring structured information. The official
specification for standard JSON can be found here: json.org. JSON is the most
common way for (modern) applications to exchange information, especially over a network.
Syntax
Here is an example of a JSON object:
{
"first_name": "John",
"last_name": "Smith",
"is_alive": true,
"age": 27,
"address": {
"street_address": "21 2nd Street",
"city": "New York",
"state": "NY",
"postal_code": "10021-3100"
},
"phone_numbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [
"Catherine",
"Thomas",
"Trevor"
],
"spouse": null
}
Structure
JSON is structured
and uses two types of structures:
- Object - a collection of members, which are
Name: Valuepairs. - Array - a list of values.
Object
An object
is a collection of members separated by commas , and enclosed within curly brackets
{..}. Each member is a name-value pair with a colon : between the name and value.
The order of members is not significant, i.e. two objects with the same members and values, but in different order are considered equal to each other.
An object can be part of a larger object by being a value of a member or item in an array.
Array
An array
is a list of values separated by commas , and enclosed within square brackets
[..].
Values can be objects or arrays (in addition to simpler types) and therefore are usually referred to as items
or
array items
.
The order of items is significant, i.e. two arrays are equal only if they contain equal items in the same order.
Value
A value
can be one of seven things:
- A string in double quotes ".."
- A number, whole (integer) or fractional (in decimal or E notation)
- An object
- An array
- true
- false
- null
String
A string
is a sequence of zero or more UTF-8 characters, enclosed in double quotes ".."
To include a " as a character in the string, it must be escaped
by a preceding it with a reverse solidus
(backslash) \. This form of escaping means that the \ must also be escaped. For example, the JSON string:
"A \"path\" to a computer file uses \\ to delimit directories on Windows."
represents the text:
A "path" to a computer file uses \ to delimit directories on Windows.
Because Planet always uses UTF-8 for JSON, any Unicode character (except the first 32 code points) can be placed in a JSON string,
but to encode a character by its Unicode code point, use \uxxxx where xxxx is four hexadecimal digits. For example, the NUL
character (ASCII code 0) is not allowed in JSON, but could be encoded into a JSON string by \u0000. There are a
few predefined escapes for JSON strings, where the letter following the \ has special meaning:
\b-backspace
, the ASCII control character 8, alternative encoding:\u0008\t-tab
, the ASCII control character 9, alternative encoding:\u0009\f-form feed
, the ASCII control character 12, alternative encoding:\u000C\n-line feed
(LF), the ASCII control character 10, alternative encoding:\u000A\r-carriage return
(CR), the ASCII control character 13, alternative encoding:\u000D
You will likely only encounder \r\n in JSON strings, which is the CR+LF pair used in most computer texts to
separate multiple lines.
Number
Unlike SQL and most programming languages, JSON (like JavaScript) has only one type for numbers. Numbers must start with a
- or a digit. Numbers may not start with a decimal point, and only the period (full stop) . may be used
to indicate a decimal separator (the character between units and tenths), regardless of your computer's regional settings.
Numbers may use E notation
.
A very important limitation to remember is that JavaScript uses a double precision float
to store all numbers in memory.
A double
cannot store a whole number larger than 9 007 199 254 740 991 which is a problem
when returning Planet entity ids to a web browser via JSON. The web browser will round the number to something that will fit
in a double (to be presented in E notation) and your code will fail with no indication of what went wrong. The only way around
this is to force entity ids to strings in the SQL that generates the JSON: SELECT Cast(EntityId AS TEXT).... Planet
does not suffer this limitation when interpreting JSON.
true & false
Rarely used in Planet, these correspond to the numbers 1 and 0, respectively, and can usually be used interchangeably with 1 or 0.
You might use these in JSON arguments for functions where
true
and false
better indicate intent, or in expressions when comparing the results
of equality tests. Note that since JSON is case-sensitive, these must be written in all lowercase. Note also that you
should not quote these, or they will become strings.
null
Null
is a term in database theory that means unknown
. In JSON objects, a member with the value of null
is equivalent to that member being completely omitted. In many cases, such members are removed before a JSON object is stored;
however, Planet will include such members in objects created by SQL to represent NULL values stored in the database,
so that a Mustache tag will not produce an error when referring to such a member.
Member names
The names of members are also known as keys
(because they are used to look up values). In standard JSON, member
names are strings, so they can contain spaces and other characters that are normally not used in programming languages for
the members of an object.
PlanetGIS uses an extension to JSON that allows unquoted names as long as they follow a few rules (not containing spaces, being one of them), but the JSON produced by a Generated JSON page will always be in the proper JSON format so that JavaScript in browsers can use it. (See below).
Whitespace
Whitespace
is unneeded spaces and line breaks used to make a JSON object more readable. JSON is should be transmitted
in the most compact form, which means no whitespace, but is best presented to a user with spaces, indentation and line breaks.
In the example above, the JSON object includes spaces after colons : and line breaks after commas ,,
opening { and [ and the last member/item in each object/array as well as spaces in front of each line to an amount required to indent each line to
better present the logical structure within.
PlanetGIS extensions to JSON
Planet's JSON implementation includes several extensions to the standard, similar to JSON5.
Unquoted keys
PlanetGIS will interpret JSON objects correctly if keys (member names) are unquoted and don't contain spaces or any of the characters that are used structurally in JSON: " \ { } [ ] , :
Planet will also produce JSON without quoted keys if they qualify according to the above rule, and Planet wasn't specifically
asked for proper
JSON. The following is valid JSON in Planet:
{
Name: "John"
}
Comments
- To-end-of-line comments:
-- this is a commentlike SQL, but ensure there is a space before--except when following a structural character (listed above), in which case the space is not required. - Nestable, multi-line comments:
/* this is a comment */like SQL and JavaScript; can appear anywhere between syntactic elements of JSON.
Multi-line strings
This is valid in PlanetGIS:
{
Text: "This is the first line
and this is the second"
}
In proper
JSON the equivalent encoding is:
{
Text: "This is the first line\n\rand this is the second"
}
Binary strings
Planet understands a string delimited by # instead of " to be Base64 encoded binary (i.e. without further special encoding; each byte is just that byte) data. Base64 uses an alphabet of 64 characters to encode bytes of data. Since 64 characters require 6 bits of storage and a byte 8 bits, every 3 bytes require 4 characters of the Base64 alphabet. (Base64 encoded data requires 33% more storage space than raw binary).
Planet outputs binary data into JSON using the
RFC 4648§5 base64url
filename-and-URL-safe alphabet, which is ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_,
without = padding.
Planet accepts binary strings in either RFC 4648§5 or RFC 4648§4 (the more common, URL-unfriendly one) and with or without
= padding. Any other character encountered in the binary string, or a = not at the end will result
in an error.
BLOB fields in the database are represented in JSON by binary strings, unless proper
JSON is requested, in which case
it will become a regular string with the same content and the recipient of the JSON object will have to know which member values
need decoding into binary.
JSON5
Some JSON5 extensions were deemed undesirable and are not implemented:
- Allowing 'single quoted strings'
- Allowing trailing commas (a , after the last member in an object or item in an array)
- Fractional numbers starting with a .