JSON
module JSON
Overview
The JSON module allows parsing and generating JSON documents.
Parsing and generating with JSON#mapping
Use JSON#mapping
to define how an object is mapped to JSON, making it the recommended easy, type-safe and efficient option for parsing and generating JSON. Refer to that module's documentation to learn about it.
Parsing with JSON#parse
JSON#parse
will return an Any
, which is a convenient wrapper around all possible JSON types, making it easy to traverse a complex JSON structure but requires some casts from time to time, mostly via some method invocations.
require "json" value = JSON.parse("[1, 2, 3]") # : JSON::Any value[0] # => 1 typeof(value[0]) # => JSON::Any value[0].as_i # => 1 typeof(value[0].as_i) # => Int32 value[0] + 1 # Error, because value[0] is JSON::Any value[0].as_i + 10 # => 11
The above is useful for dealing with a dynamic JSON structure but is slower than using JSON#mapping
.
Generating with JSON.build
Use JSON.build
, which uses JSON::Builder
, to generate JSON by emitting scalars, arrays and objects:
require "json" string = JSON.build do |json| json.object do json.field "name", "foo" json.field "values" do json.array do json.number 1 json.number 2 json.number 3 end end end end string # => %<{"name":"foo","values":[1,2,3]}>
Generating with to_json
to_json
, to_json(IO)
and to_json(JSON::Builder)
methods are provided for primitive types, but you need to define to_json(JSON::Builder)
for custom objects, either manually or using JSON#mapping
.
Defined in:
json.crjson/builder.cr
json/mapping.cr
Class Method Summary
- .build(io : IO, indent = nil, &block)
Writes JSON into the given
IO
- - .build(indent = nil, &block)
Returns the resulting
String
of writing JSON to the yieldedJSON::Builder
. - .parse(input : String | IO) : Any
Parses a JSON document as a
JSON::Any
. - .parse_raw(input : String | IO) : Type
Parses a JSON document as a
JSON::Type
.
Macro Summary
- mapping(properties, strict = false)
The
JSON.mapping
macro defines how an object is mapped to JSON. - mapping
This is a convenience method to allow invoking
JSON.mapping
with named arguments instead of with a hash/named-tuple literal.
Class Method Detail
def self.build(io : IO, indent = nil, &block)Source
Writes JSON into the given IO
- A JSON::Builder
is yielded to the block.
def self.build(indent = nil, &block)Source
Returns the resulting String
of writing JSON to the yielded JSON::Builder
.
require "json" string = JSON.build do |json| json.object do json.field "name", "foo" json.field "values" do json.array do json.number 1 json.number 2 json.number 3 end end end end string # => %<{"name":"foo","values":[1,2,3]}>
def self.parse_raw(input : String | IO) : TypeSource
Parses a JSON document as a JSON::Type
.
Macro Detail
macro mapping(properties, strict = false)Source
The JSON.mapping
macro defines how an object is mapped to JSON.
Example
require "json" class Location JSON.mapping( lat: Float64, lng: Float64, ) end class House JSON.mapping( address: String, location: {type: Location, nilable: true}, ) end house = House.from_json(%({"address": "Crystal Road 1234", "location": {"lat": 12.3, "lng": 34.5}})) house.address # => "Crystal Road 1234" house.location # => #<Location:0x10cd93d80 @lat=12.3, @lng=34.5> house.to_json # => %({"address":"Crystal Road 1234","location":{"lat":12.3,"lng":34.5}})
Usage
JSON.mapping
must receive a series of named arguments, or a named tuple literal, or a hash literal, whose keys will define Crystal properties.
The value of each key can be a single type (not a union type). Primitive types (numbers, string, boolean and nil) are supported, as well as custom objects which use JSON.mapping
or define a new
method that accepts a JSON::PullParser
and returns an object from it.
The value can also be another hash literal with the following options:
-
type: (required) the single type described above (you can use
JSON::Any
too) - key: the property name in the JSON document (as opposed to the property name in the Crystal code)
-
nilable: if
true
, the property can beNil
- PassingT?
as a type has the same effect- -
default: value to use if the property is missing in the JSON document, or if it's
null
andnilable
was not set totrue
- If the default value creates a new instance of an object (for example[1, 2, 3]
orSomeObject-new
), a different instance will be used each time a JSON document is parsed- -
emit_null: if
true
, emits anull
value for nilable properties (by default nulls are not emitted) -
converter: specify an alternate type for parsing and generation- The converter must define
from_json(JSON::PullParser)
andto_json(value, JSON::Builder)
as class methods. Examples of converters areTime::Format
andTime::EpochConverter
forTime
. -
root: assume the value is inside a JSON object with a given key (see
Object.from_json(string_or_io, root)
) -
setter: if
true
, will generate a setter for the variable,true
by default -
getter: if
true
, will generate a getter for the variable,true
by default
This macro by default defines getters and setters for each variable (this can be overrided with setter and getter). The mapping doesn't define a constructor accepting these variables as arguments, but you can provide an overload.
The macro basically defines a constructor accepting a JSON::PullParser
that reads from it and initializes this type's instance variables. It also defines a to_json(JSON::Builder)
method by invoking to_json(JSON::Builder)
on each of the properties (unless a converter is specified, in which case to_json(value, JSON::Builder)
is invoked).
This macro also declares instance variables of the types given in the mapping.
If strict is true
, unknown properties in the JSON document will raise a parse exception. The default is false
, so unknown properties are silently ignored.
macro mappingSource
This is a convenience method to allow invoking JSON.mapping
with named arguments instead of with a hash/named-tuple literal.
© 2012–2017 Manas Technology Solutions.
Licensed under the Apache License, Version 2.0.
https://crystal-lang.org/api/0.22.0/JSON.html