|
| 1 | +# jsonapi-deserializable |
| 2 | +Ruby gem for deserializing [JSON API](http://jsonapi.org) payloads into custom |
| 3 | +hashes. |
| 4 | + |
| 5 | +## Status |
| 6 | + |
| 7 | +[](https://badge.fury.io/rb/jsonapi-deserializable) |
| 8 | +[](http://travis-ci.org/jsonapi-rb/deserializable?branch=master) |
| 9 | + |
| 10 | +## Table of Contents |
| 11 | + |
| 12 | + - [Installation](#installation) |
| 13 | + - [Usage/Examples](#usageexamples) |
| 14 | + - [Documentation](#documentation) |
| 15 | + - [Common methods](#common-methods) |
| 16 | + - [`JSONAPI::Deserializable::Resource` DSL](#jsonapideserializableresource-dsl) |
| 17 | + - [`JSONAPI::Deserializable::Relationship` DSL](#jsonapideserializablerelationship-dsl) |
| 18 | + - [License](#license) |
| 19 | + |
| 20 | +## Installation |
| 21 | +```ruby |
| 22 | +# In Gemfile |
| 23 | +gem 'jsonapi-deserializable' |
| 24 | +``` |
| 25 | +then |
| 26 | +``` |
| 27 | +$ bundle |
| 28 | +``` |
| 29 | +or manually via |
| 30 | +``` |
| 31 | +$ gem install jsonapi-deserializable |
| 32 | +``` |
| 33 | + |
| 34 | +## Usage/Examples |
| 35 | + |
| 36 | +First, require the gem: |
| 37 | +```ruby |
| 38 | +require 'jsonapi/deserializable' |
| 39 | +``` |
| 40 | + |
| 41 | +Then, define some resource/relationship deserializable classes: |
| 42 | + |
| 43 | +### Resource Example |
| 44 | + |
| 45 | +```ruby |
| 46 | +class DeserializablePost < JSONAPI::Deserializable::Resource |
| 47 | + type |
| 48 | + attribute :title |
| 49 | + attribute :date { |date| field date: DateTime.parse(date) } |
| 50 | + has_one :author do |rel, id, type| |
| 51 | + field author_id: id |
| 52 | + field author_type: type |
| 53 | + end |
| 54 | + has_many :comments do |rel, ids, types| |
| 55 | + field comment_ids: ids |
| 56 | + field comment_types: types.map do |type| |
| 57 | + camelize(singularize(type)) |
| 58 | + end |
| 59 | + end |
| 60 | +end |
| 61 | +``` |
| 62 | + |
| 63 | +which can then be used to deserialize post payloads: |
| 64 | +```ruby |
| 65 | +DeserializablePost.(payload) |
| 66 | +# => { |
| 67 | +# id: '1', |
| 68 | +# title: 'Title', |
| 69 | +# date: #<DateTime: 2016-01-10T02:30:00+00:00 ((2457398j,9000s,0n),+0s,2299161j)>, |
| 70 | +# author_id: '1337', |
| 71 | +# author_type: 'users', |
| 72 | +# comment_ids: ['123', '234', '345'] |
| 73 | +# comment_types: ['Comment', 'Comment', 'Comment'] |
| 74 | +# } |
| 75 | +``` |
| 76 | + |
| 77 | +### Relationship Example |
| 78 | + |
| 79 | +```ruby |
| 80 | +class DeserializablePostComments < JSONAPI::Deserializable::Relationship |
| 81 | + has_many do |rel, ids, types| |
| 82 | + field comment_ids: ids |
| 83 | + field comment_types: types.map do |ri| |
| 84 | + camelize(singularize(type)) |
| 85 | + end |
| 86 | + field comments_meta: rel['meta'] |
| 87 | + end |
| 88 | +end |
| 89 | +``` |
| 90 | +```ruby |
| 91 | +DeserializablePostComments.(payload) |
| 92 | +# => { |
| 93 | +# comment_ids: ['123', '234', '345'] |
| 94 | +# comment_types: ['Comment', 'Comment', 'Comment'] |
| 95 | +# } |
| 96 | +``` |
| 97 | + |
| 98 | +## Documentation |
| 99 | + |
| 100 | +Whether deserializaing a resource or a relationship, the base idea is the same: |
| 101 | +for every part of the payload, simply declare the fields you want to build from |
| 102 | +their value. You can create as many fields as you want out of any one part of |
| 103 | +the payload. |
| 104 | + |
| 105 | +It works according to a whitelisting mechanism: should the corresponding part of |
| 106 | +the payload not be present, the fields will simply not be created on the result |
| 107 | +hash. |
| 108 | + |
| 109 | +Note however that the library expects well formed JSONAPI payloads (which you |
| 110 | +can ensure using, for instance, |
| 111 | +[jsonapi-parser](https://github.com/beauby/jsonapi/tree/master/parser)), |
| 112 | +and that deserialization does not substitute itself to validation of the |
| 113 | +resulting hash (which you can handle using, for instance, |
| 114 | +[dry-validation](http://dry-rb.org/gems/dry-validation/)). |
| 115 | + |
| 116 | +### Common Methods |
| 117 | + |
| 118 | ++ `::field(hash)` |
| 119 | + |
| 120 | +The `field` DSL method is the base of jsonapi-deserializable. It simply declares |
| 121 | +a field of the result hash, with its value. The syntax is: |
| 122 | +```ruby |
| 123 | +field key: value |
| 124 | +``` |
| 125 | + |
| 126 | +It is mainly used within the following DSL contexts, but can be used outside of |
| 127 | +any to declare custom non payload-related fields. |
| 128 | + |
| 129 | ++ `#initialize(payload)` |
| 130 | + |
| 131 | +Build a deserializable instance, ready to be deserialized by calling `#to_h`. |
| 132 | + |
| 133 | ++ `#to_h` |
| 134 | + |
| 135 | +In order to deserialize a payload, simply do: |
| 136 | +```ruby |
| 137 | +DeserializablePost.new(payload).to_h |
| 138 | +``` |
| 139 | +or use the shorthand syntax: |
| 140 | +```ruby |
| 141 | +DeserializablePost.(payload) |
| 142 | +``` |
| 143 | + |
| 144 | +### `JSONAPI::Deserializable::Resource` DSL |
| 145 | + |
| 146 | ++ `::type(&block)` |
| 147 | +```ruby |
| 148 | +type do |type| |
| 149 | + field my_type_field: type |
| 150 | +end |
| 151 | +``` |
| 152 | + |
| 153 | +Shorthand syntax: |
| 154 | +```ruby |
| 155 | +type |
| 156 | +``` |
| 157 | + |
| 158 | ++ `::id(&block)` |
| 159 | +```ruby |
| 160 | +id do |id| |
| 161 | + field my_id_field: id |
| 162 | +end |
| 163 | +``` |
| 164 | + |
| 165 | +Shorthand syntax: |
| 166 | +```ruby |
| 167 | +id |
| 168 | +``` |
| 169 | + |
| 170 | ++ `::attribute(key, &block)` |
| 171 | +```ruby |
| 172 | +attribute :title do |title| |
| 173 | + field my_title_field: title |
| 174 | +end |
| 175 | +``` |
| 176 | + |
| 177 | +Shorthand syntax: |
| 178 | +```ruby |
| 179 | +attribute :title |
| 180 | +``` |
| 181 | + |
| 182 | ++ `::has_one(key, &block)` |
| 183 | +```ruby |
| 184 | +has_one :author do |rel, id, type| |
| 185 | + field my_author_type_field: type |
| 186 | + field my_author_id_field: id |
| 187 | + field my_author_meta_field: rel['meta'] |
| 188 | +end |
| 189 | +``` |
| 190 | + |
| 191 | +Shorthand syntax: |
| 192 | +```ruby |
| 193 | +has_one :author |
| 194 | +``` |
| 195 | +Note: this creates a field `:author` with value the whole relationship hash. |
| 196 | + |
| 197 | ++ `::has_many(key, &block)` |
| 198 | +```ruby |
| 199 | +has_many :comments do |rel, ids, types| |
| 200 | + field my_comment_types_field: types |
| 201 | + field my_comment_ids_field: ids |
| 202 | + field my_comment_meta_field: rel['meta'] |
| 203 | +end |
| 204 | +``` |
| 205 | + |
| 206 | +Shorthand syntax: |
| 207 | +```ruby |
| 208 | +has_many :comments |
| 209 | +``` |
| 210 | +Note: this creates a field `:comments` with value the whole relationship hash. |
| 211 | + |
| 212 | +### `JSONAPI::Deserializable::Relationship` DSL |
| 213 | + |
| 214 | ++ `::has_one(key, &block)` |
| 215 | +```ruby |
| 216 | +has_one do |rel, id, type| |
| 217 | + field my_relationship_id_field: id |
| 218 | + field my_relationship_type_field: type |
| 219 | + field my_relationship_meta_field: rel['meta'] |
| 220 | +end |
| 221 | +``` |
| 222 | + |
| 223 | ++ `has_many(key, &block)` |
| 224 | +```ruby |
| 225 | +has_many do |rel, ids, types| |
| 226 | + field my_relationship_ids_field: ids |
| 227 | + field my_relationship_types_field: types |
| 228 | + field my_relationship_meta_field: rel['meta'] |
| 229 | +end |
| 230 | +``` |
| 231 | + |
| 232 | +## License |
| 233 | + |
| 234 | +jsonapi-deserializable is released under the [MIT License](http://www.opensource.org/licenses/MIT). |
0 commit comments