Top.Mail.Ru
Module json | Tarantool
 

Module json

Module json

Overview

The json module provides JSON manipulation routines. It is based on the Lua-CJSON module by Mark Pulford. For a complete manual on Lua-CJSON please read the official documentation.

Index

Below is a list of all json functions and members.

Name Use
json.encode() Convert a Lua object to a JSON string
json.decode() Convert a JSON string to a Lua object
__serialize parameter Output structure specification
json.cfg() Change configuration
json.NULL Analog of Lua’s “nil”
json.encode(lua-value[, configuration])

Convert a Lua object to a JSON string.

Parameters:
  • lua_value – either a scalar value or a Lua table value.
  • configuration – see json.cfg
Return:

the original value reformatted as a JSON string.

Rtype:

string

Example:

tarantool> json=require('json')
---
...
tarantool> json.encode(123)
---
- '123'
...
tarantool> json.encode({123})
---
- '[123]'
...
tarantool> json.encode({123, 234, 345})
---
- '[123,234,345]'
...
tarantool> json.encode({abc = 234, cde = 345})
---
- '{"cde":345,"abc":234}'
...
tarantool> json.encode({hello = {'world'}})
---
- '{"hello":["world"]}'
...
json.decode(string[, configuration])

Convert a JSON string to a Lua object.

Parameters:
  • string (string) – a string formatted as JSON.
  • configuration – see json.cfg
Return:

the original contents formatted as a Lua table.

Rtype:

table

Example:

tarantool> json = require('json')
---
...
tarantool> json.decode('123')
---
- 123
...
tarantool> json.decode('[123, "hello"]')
---
- [123, 'hello']
...
tarantool> json.decode('{"hello": "world"}').hello
---
- world
...

See the tutorial Sum a JSON field for all tuples to see how json.decode() can fit in an application.

__serialize parameter:

The JSON output structure can be specified with __serialize:

  • ‘seq’, ‘sequence’, ‘array’ - table encoded as an array
  • ‘map’, ‘mapping’ - table encoded as a map
  • function - the meta-method called to unpack serializable representation of table, cdata or userdata objects

Serializing ‘A’ and ‘B’ with different __serialize values brings different results:

tarantool> json.encode(setmetatable({'A', 'B'}, { __serialize="seq"}))
---
- '["A","B"]'
...
tarantool> json.encode(setmetatable({'A', 'B'}, { __serialize="map"}))
---
- '{"1":"A","2":"B"}'
...
tarantool> json.encode({setmetatable({f1 = 'A', f2 = 'B'}, { __serialize="map"})})
---
- '[{"f2":"B","f1":"A"}]'
...
tarantool> json.encode({setmetatable({f1 = 'A', f2 = 'B'}, { __serialize="seq"})})
---
- '[[]]'
...
json.cfg(table)

Set values that affect the behavior of json.encode and json.decode.

The values are all either integers or boolean true/false.

Option Default Use
cfg.encode_max_depth 128 Max recursion depth for encoding
cfg.encode_deep_as_nil false A flag saying whether to crop tables with nesting level deeper than cfg.encode_max_depth. Not-encoded fields are replaced with one null. If not set, too deep nesting is considered an error.
cfg.encode_invalid_numbers true A flag saying whether to enable encoding of NaN and Inf numbers
cfg.encode_number_precision 14 Precision of floating point numbers
cfg.encode_load_metatables true A flag saying whether the serializer will follow __serialize metatable field
cfg.encode_use_tostring false A flag saying whether to use tostring() for unknown types
cfg.encode_invalid_as_nil false A flag saying whether use NULL for non-recognized types
cfg.encode_sparse_convert true A flag saying whether to handle excessively sparse arrays as maps. See detailed description below.
cfg.encode_sparse_ratio 2 1/encode_sparse_ratio is the permissible percentage of missing values in a sparse array.
cfg.encode_sparse_safe 10 A limit ensuring that small Lua arrays are always encoded as sparse arrays (instead of generating an error or encoding as a map)
cfg.decode_invalid_numbers true A flag saying whether to enable decoding of NaN and Inf numbers
cfg.decode_save_metatables true A flag saying whether to set metatables for all arrays and maps
cfg.decode_max_depth 128 Max recursion depth for decoding

Sparse arrays features:

During encoding, the JSON encoder tries to classify a table into one of four kinds:

  • map - at least one table index is not unsigned integer
  • regular array - all array indexes are available
  • sparse array - at least one array index is missing
  • excessively sparse array - the number of values missing exceeds the configured ratio

An array is excessively sparse when all the following conditions are met:

  • encode_sparse_ratio > 0
  • max(table) > encode_sparse_safe
  • max(table) > count(table) * encode_sparse_ratio

The JSON encoder will never consider an array to be excessively sparse when encode_sparse_ratio = 0. The encode_sparse_safe limit ensures that small Lua arrays are always encoded as sparse arrays. By default, attempting to encode an excessively sparse array will generate an error. If encode_sparse_convert is set to true, excessively sparse arrays will be handled as maps.

json.cfg() example 1:

The following code will encode 0/0 as NaN (“not a number”) and 1/0 as Inf (“infinity”), rather than returning nil or an error message:

json = require('json')
json.cfg{encode_invalid_numbers = true}
x = 0/0
y = 1/0
json.encode({1, x, y, 2})

The result of the json.encode() request will look like this:

tarantool> json.encode({1, x, y, 2})
---
- '[1,nan,inf,2]
...

json.cfg example 2:

To avoid generating errors on attempts to encode unknown data types as userdata/cdata, you can use this code:

tarantool> httpc = require('http.client').new()
---
...

tarantool> json.encode(httpc.curl)
---
- error: unsupported Lua type 'userdata'
...

tarantool> json.encode(httpc.curl, {encode_use_tostring=true})
---
- '"userdata: 0x010a4ef2a0"'
...

Note

To achieve the same effect for only one call to json.encode() (i.e. without changing the configuration permanently), you can use json.encode({1, x, y, 2}, {encode_invalid_numbers = true}).

Similar configuration settings exist for MsgPack and YAML.

json.NULL

A value comparable to Lua “nil” which may be useful as a placeholder in a tuple.

Example:

-- When nil is assigned to a Lua-table field, the field is null
tarantool> {nil, 'a', 'b'}
---
- - null
  - a
  - b
...
-- When json.NULL is assigned to a Lua-table field, the field is json.NULL
tarantool> {json.NULL, 'a', 'b'}
---
- - null
  - a
  - b
...
-- When json.NULL is assigned to a JSON field, the field is null
tarantool> json.encode({field2 = json.NULL, field1 = 'a', field3 = 'c'})
---
- '{"field2":null,"field1":"a","field3":"c"}'
...