Rackson
Rackson serves to turn JSON into ruby objects. Where Rackson differs from other libraries is that the classes are expected to be already defined so that if you use the wrong input or try to call a method that doesn't exist it will raise an exception as soon as possible
Installation
Add this line to your application's Gemfile:
gem 'rackson'
And then execute:
$ bundle
Or install it yourself as:
$ gem install rackson
Usage
Let's just start with a very simple example
class Foo
include Rackson
json_property :bar, String
end
mapper = Rackson::ObjectMapper.new
foo = mapper.deserialize('{ "bar": "value" }', Foo)
foo.bar
# 'value'
mapper.serialize(foo)
# {"bar":"value"}
As you can see after including Rackson
the class now has access to a
json_property
method which defines a new property. The first argument is the
key, the second is the type. This way if you pass something not a string you
will get an exception when trying to deserialize instead of later. The class can
be whatever you want:
class Inner
include Rackson
json_property :foo, String
end
class Outer
include Rackson
json_property :inner, Inner
end
mapper = Rackson::ObjectMapper.new
outer = mapper.deserialize('{ "outer": { "foo": "bar" }}', Outer)
outer.inner.foo
# 'bar'
Unless specified otherwise, all properties are required:
class Foo
include Rackson
json_property :foo, String
json_property :bar, String
end
mapper = Rackson::ObjectMapper.new
foo = mapper.deserialize('{ "foo": "this is foo" }', Foo)
# Rackson::DeserializationError: missing required key bar
However, properties are easily marked as optional:
class Foo
include Rackson
json_property :foo, String
json_property :bar, String, optional: true
end
mapper = Rackson::ObjectMapper.new
foo = mapper.deserialize('{ "foo": "this is foo" }', Foo)
foo.bar
# nil
Initializers
You may have noticed that none of the example classes defined #initialize
, so
rackson could just call Foo.new
with no problems. Rackson prefers you to
either have no initialize method, or define one with all optional arguments,
though it can deal with classes otherwise by not calling the initializer:
class Foo
include Rackson
json_property :foo, String
attr_reader :bar
def initialize(required)
@bar = 'bar'
end
end
foo = mapper.deserialize '{ "foo": "this is foo" }', Foo
foo.foo
# "this is foo"
foo.bar
# nil
Rackson has skipped calling #initialize
, instead using Object#allocate
. This
seems kind of hacky to me, and I may consider adding an optional log warning, or
removing the feature entirely. Nevertheless it works for now.
Contributing
- Fork it ( https://github.com/griffindy/rackson/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request