module JSON
Overview
The JSON module allows parsing and generatingJSON documents.
NOTE To useJSON or its children, you must explicitly import it withrequire "json"
General type-safe interface
The general type-safe interface for parsing JSON is to invokeT.from_json on a
target typeT and pass either aString orIO as an argument.
require "json"
json_text = %([1, 2, 3])
Array(Int32).from_json(json_text) # => [1, 2, 3]
json_text = %({"x": 1, "y": 2})
Hash(String, Int32).from_json(json_text) # => {"x" => 1, "y" => 2}
Serializing is achieved by invokingto_json, which returns aString, or
to_json(io : IO), which will stream the JSON to anIO.
require "json"
[1, 2, 3].to_json # => "[1,2,3]"
{"x" => 1, "y" => 2}.to_json # => "{\"x\":1,\"y\":2}"
Most types in the standard library implement these methods. For user-defined types
you can define aself.new(pull : JSON::PullParser) for parsing and
to_json(builder : JSON::Builder) for serializing. The following sections
show convenient ways to do this usingJSON::Serializable.
NOTE JSON object keys are always strings but they can still be parsed
and deserialized to other types. To deserialize, define a
T.from_json_object_key?(key : String) : T? method, which can returnnil
if the string can't be parsed into that type. To serialize, define a
to_json_object_key : String method can be serialized that way.
All integer and float types in the standard library can be deserialized that way.
require "json"
json_text = %({"1": 2, "3": 4})
Hash(Int32, Int32).from_json(json_text) # => {1 => 2, 3 => 4}
{1.5 => 2}.to_json # => "{\"1.5\":2}"
Parsing withJSON.parse
JSON.parse will return anAny, 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].as_i? # => 1
typeof(value[0].as_i?) # => Int32 | Nil
value[0].as_s? # => nil
typeof(value[0].as_s?) # => String | Nil
value[0] + 1 # Error, because value[0] is JSON::Any
value[0].as_i + 10 # => 11
JSON.parse can read from anIO directly (such as a file) which saves
allocating a string:
require "json"
json = File.open("path/to/file.json") do |file|
JSON.parse(file)
end
Parsing withJSON.parse is useful for dealing with a dynamic JSON structure.
Generating withJSON.build
UseJSON.build, which usesJSON::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 withto_json
to_json,to_json(IO) andto_json(JSON::Builder) methods are provided
for primitive types, but you need to defineto_json(JSON::Builder)
for custom objects, either manually or usingJSON::Serializable.
Defined in:
json.crjson/builder.cr
json/serialization.cr
Class Method Summary
-
.build(indent : String | Int | Nil = nil, &)
Returns the resulting
Stringof writing JSON to the yieldedJSON::Builder. -
.build(io : IO, indent : String | Int | Nil = nil, &) : Nil
Writes JSON into the given
IO. -
.parse(input : String | IO) : Any
Parses a JSON document as a
JSON::Any.
Class Method Detail
Returns the resultingString of writing JSON to the yieldedJSON::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]}>
Accepts an indent parameter which can either be anInt (number of spaces to indent)
or aString, which will prefix each level with the string a corresponding amount of times.