Skip to content

Working with JSON

How ELPS reads and writes JSON, and the rules for numbers, null, keys, canonical bytes and typed JSON.

Most phylum endpoints read JSON and write JSON. The json package converts between JSON and ELPS values. This page gives the rules that matter in a phylum: how numbers, null and keys convert, and how to get the same bytes on every peer.

Every example on this page runs in your browser. Edit an example to see the new result.


How JSON converts

JSON ELPS value after json:load-string
object sorted map with string keys
array vector
string string
number float, also when it has no fraction (see Numbers)
true, false the symbols true and false
null ()

json:dump-string and json:dump-bytes convert the other way. A list dumps as a JSON array. () dumps as null.


Numbers

Every JSON number loads as a float. 2500 loads as the float 2500. This has two effects:

  • A function that needs an int, such as nth, refuses the value. A schema check with s:int fails. Use s:number.
  • An integer above 2^53 (9007199254740992) is rounded, and nothing reports it. Two different IDs can load as the same value.

Give :exact-integers true to a load function to keep each number that is written without a . or an exponent as an exact int:

With :exact-integers true, an integer too large for an ELPS int raises json:integer-range-error in place of a rounded value. Another way to keep a large ID exact is to send it as a JSON string and convert it with to-int.


null

A JSON null loads as (). So a key with the value null and a missing key read the same with get. Use key? to tell them apart:

To write null, dump () or the value json:null.


Keys

A JSON object loads as a sorted map with string keys. get also accepts a symbol with the same name, but keys always returns strings.

A keyword keeps its colon when you dump it: (sorted-map :height 1) dumps as {":height":1}. Use string keys for JSON.


Canonical JSON for hashes and keys

Every endorser must compute the same bytes. When you hash a value, or build a state key from it, dump it in canonical form: (json:dump-string value :canonize true). Canonical form converts symbols and keywords to strings, lists to vectors, bytes to base64 strings and whole-number floats to ints, and sorts the keys. Every elps version gives the same canonical bytes for the same value.

A value that canonical form cannot hold exactly, such as an int above 2^53 or NaN, raises json:canonize-error.


Typed JSON

Plain JSON loses types: 5 and 5.0 dump the same, a symbol comes back as a string and a list comes back as a vector. To store an ELPS value and get the same value back, dump it with :typed true and load it with :typed true. The output is still JSON. Only the values that plain JSON cannot tell apart get a short tag that starts with ~.

ELPS value Plain JSON Typed JSON
5 5 5
5.0 5 "~d5"
:kw ":kw" "~:kw"
'sym "sym" "~$sym"
'(1 2) [1,2] ["~#list",[1,2]]
(vector 1 2) [1,2] [1,2]
"~x" "~x" "~~x"

We use cookies to give you the best experience of using this website. By continuing to use this site, you accept our use of cookies. Please read our Cookie Policy for more information.