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:

  1. Object - a collection of members, which are Name: Value pairs.
  2. 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:

  1. A string in double quotes ".."
  2. A number, whole (integer) or fractional (in decimal or E notation)
  3. An object
  4. An array
  5. true
  6. false
  7. 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 comment like 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 .

Generating JSON with SQL