Skip to content

Update docs. #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 1 addition & 181 deletions source/guides/deserialization/defining.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,184 +6,4 @@ layout: guides
Custom deserializable resources are defined by subclassing
`JSONAPI::Deserializable::Resource` and using its DSL.

Example:

```ruby
class DeserializablePost < JSONAPI::Deserializable::Resource
attribute :date do |attr|
{ created_at: attr }
end

relationship :author do |_rel, id, type|
{ user_id: id,
user_type: type }
end

relationship :comments do |_rel, ids, _types|
{ response_ids: ids }
end
end

# Will allow to build the following hash:
# => {
# type: 'posts',
# id: '5',
# created_at: '2016-11-18',
# title: 'Hello JSON API',
# user_id: '12',
# user_type: 'users',
# response_ids: ['54', '32', '72']
# }
```

The principle is simple: the payload elements for which a custom deserialization
scheme was defined will use that, while other fields will be deserialized using
the default deserialization scheme (which can itself be configured).

Note: If the targeted element does not exist in the payload, the corresponding
fields are not defined.

## Type

The type of the primary data can be accessed via the `type` DSL method.

Example:

```ruby
class DeserializablePost < JSONAPI::Deserializable::Post
# ...
type do |t|
{ primary_type: t.capitalize }
end
end
```

## Id

The id of the primary data can be accessed via the `id` DSL method.

Example:

```ruby
class DeserializablePost < JSONAPI::Deserializable::Post
# ...
id do |i|
{ primary_id: i.to_i }
end
end
```

## Attributes

Attributes of the primary data can be accessed via the `attribute` DSL method.
The `attribute` method takes a symbol representing the name of the targeted
attribute in the input payload, and a block to define field(s) of the resulting
hash.

Example:

```ruby
class DeserializablePost < JSONAPI::Deserializable::Post
# ...
attribute :date do |d|
{ created_at: d }
end
end
```

## Relationships

Relationships of the primary data can be accessed via the `has_many` and
`has_one` DSL methods.

### To-many relationships

The `has_many` DSL method takes a symbol representing the name of the targeted
relationship in the input payload, and a block to define field(s) of the
resulting hash. The block is called with three parameters: `relationship` (the
whole relationship hash of the input payload), `ids` (an array of the ids of
related resources), and `types` (an array of types of the related resources).

Example:

```ruby
class DeserializablePost < JSONAPI::Deserializable::Post
# ...
has_many :comments do |rel, ids, types|
{ comment_ids: ids,
comment_types: types.map(&:capitalize),
comment_meta: rel['meta'] }
end
end
```

### To-one relationships

The `has_one` DSL method takes a symbol representing the name of the targeted
relationship in the input payload, and a block to define field(s) of the
resulting hash. The block is called with three parameters: `relationship` (the
whole relationship hash of the input payload), `id` (the id of the related
resource), and `type` (the type of the related resource).

Example:

```ruby
class DeserializablePost < JSONAPI::Deserializable::Post
# ...
has_one :author do |rel, id, type|
{ author_id: id,
author_type: type.capitalize,
author_meta: rel['meta'] }
end
end
```

## Meta

Not available yet.

## Links

Not available yet.

## Configuration

The default deserialization scheme can be configure in the following way:

```ruby
# Modifying the global default deserialization scheme
JSONAPI::Deserializable::Resource.configure do |config|
config.default_id = proc { |id| { id: id } }
config.default_type = proc { |type| { type: type } }
config.default_attribute = proc do |key, value|
{ key => value }
end
config.default_has_one = proc do |key, rel, id, type|
{ "#{key}_id}".to_sym => id, "#{key}_type".to_sym => type }
end
config.default_has_many = proc do |key, rel, ids, types|
{ "#{key}_ids}".to_sym => ids, "#{key}_types".to_sym => types }
end
end

# Modifying the default deserialization scheme of a single deserializable
# resource class

class DeserializablePost < JSONAPI::Deserializable::Resource
# ...
end

DeserializablePost.configure do |config|
config.default_id = proc { |id| { id: id } }
config.default_type = proc { |type| { type: type } }
config.default_attribute = proc do |key, value|
{ key => value }
end
config.default_has_one = proc do |key, rel, id, type|
{ "#{key}_id".to_sym => id, "#{key}_type".to_sym => type }
end
config.default_has_many = proc do |key, rel, ids, types|
{ "#{key}_ids".to_sym => ids, "#{key}_types".to_sym => types }
end
end
```
Documentation currently being rewritten.
20 changes: 2 additions & 18 deletions source/guides/deserialization/deserializing.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,7 @@ layout: guides
Deserializing an input payload is straightforward: simply call the
deserializable resource.

Example (generic deserializable resource):

```ruby
JSONAPI::Deserializable::Resource.call(json_hash)
# => {
# type: 'posts',
# id: '5',
# title: 'Hello JSON API',
# date: '2016-11-18',
# author_id: '12',
# author_type: 'users',
# comments_ids: ['54', '32', '72']
# comments_types: ['comments', 'comments', 'comments']
# }
```

Example (custom deserializable resource):
Example:

```ruby
DeserializablePost.call(json_hash)
Expand Down Expand Up @@ -58,7 +42,7 @@ Example:

```ruby
class PostsController < ApplicationController
deserializable_resource :post, DeserializablePost, only: [:create, :update]
deserializable_resource :post, class: DeserializablePost, only: [:create, :update]

# ...

Expand Down
9 changes: 3 additions & 6 deletions source/guides/deserialization/index.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@ layout: guides
---
# Deserialization

Any resource payload can be deserialized into a standardized format using the
`JSONAPI::Deserializable::Resource` class. In case you need more control over
the generated hash (modifying some field names, or modifying the default
deserialization scheme for attributes/relationships), you can define custom
*deserializable resources*. Deserializable resources map the members of a
payload to fields of a hash. They are defined via an intuitive DSL.
Deserializable resources map the members of a payload to fields of a hash.
They are defined by subclassing `JSONAPI::Deserializable::Resource` via an
intuitive DSL.

Once your deserializable resources are defined, you can call them on hashes
representing input JSON API payloads, and obtain a hash that you can use
Expand Down
15 changes: 2 additions & 13 deletions source/guides/index.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ validation of JSON API documents,
+ [jsonapi-renderer](https://github.com/jsonapi-rb/renderer) for low-level
rendering of JSON API documents,
+ [jsonapi-serializable](https://github.com/jsonapi-rb/serializable) for
building serializable resource classes from your business object,
building serializable resource classes from your business object -- those are
usually referred to as "serializers" in other libs,
+ [jsonapi-deserializable](https://github.com/jsonapi-rb/deserializable) for
building deserializable resource classes that transform an incoming JSON API
payload into a custom hash,
Expand All @@ -29,18 +30,6 @@ generators,
[Hanami](http://hanamirb.org) with Hanami::Controller::Action integration and
(soon) generators.

## Overview

jsonapi-rb works by defining *mappers* (or *presenters*) to translate your
business objects to JSON API documents, and JSON API payloads to custom hashes.

The *deserializable resources* (the mappers from JSON API payloads to custom
hashes) can be used directly, as the input payload will only contain flat data.

The *serializable resources*, on the other hand, need to be coordinated through
a *renderer* (as JSON API response document usually contain a graph of resources
related to each other).

## Guides

These guides should get you up to speed with using jsonapi-rb. If you have more
Expand Down
41 changes: 22 additions & 19 deletions source/guides/serialization/defining.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class SerializablePost < JSONAPI::Serializable::Resource

belongs_to :author

has_many :comments, class: 'V2::SerializableComment' do
has_many :comments do
data do
@object.published_comments
end
Expand All @@ -45,25 +45,32 @@ end
```

The principle is simple: you declare elements of the JSON API resource and
specify their values.
optionally specify their values.

The underying object is available throughout the DSL as the instance variable
`@object`. (In general, all *exposures* - that is, variables made available in
the `render` call - are available throughout the DSL as instance variables.)
the `render` call via the `expose` option - are available throughout the DSL
as instance variables.)

## Type

The `type` property is declared via the DSL method of the same name, and takes
a symbol or a string.
a symbol, a string, or a block.

Example:
Examples:

```ruby
class SerializablePost < JSONAPI::Serializable::Resource
type 'posts'
end
```

```ruby
class SerializablePost < JSONAPI::Serializable::Resource
type { @object.type }
end
```

## Id

The `id` property is declared via the DSL method of the same name, and takes a
Expand Down Expand Up @@ -92,6 +99,11 @@ Example:
class SerializablePost < JSONAPI::Serializable::Resource
# ...
attribute :date # This will have value @object.date
```

```ruby
class SerializablePost < JSONAPI::Serializable::Resource
# ...
attribute :date do
@object.created_at
end
Expand All @@ -111,13 +123,13 @@ class SerializablePost < JSONAPI::Serializable::Resource
meta foo: 'bar'
end
```
or dynamically in a block:
or dynamically in a block (in case it needs access to the exposures):

```ruby
class SerializablePost < JSONAPI::Serializable::Resource
# ...
meta do
{ foo: 'bar' }
{ foo: @object.foo }
end
end
```
Expand Down Expand Up @@ -237,20 +249,11 @@ class SerializablePost < JSONAPI::Serializable::Resource
end
```

Note that while this usage is supported, it is actually recommended to set a
global explicit mapping at the renderer level.

### Linkage data overriding

Note: it is also possible to manually override the linkage data for a
relationship (which can be useful to add linkage-level meta information) via the
`linkage` DSL method.

## Rails generators

The jsonapi-rails gem comes with generators for serializable resource classes.
It infers the attributes and relationships from your model definition.

Usage:

```
$ bundle exec rails generate jsonapi:serializable Post
> created app/serializable/serializable_post.rb
```
6 changes: 4 additions & 2 deletions source/guides/serialization/index.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ layout: guides

In order to build JSON API documents from your data, you need to define some
*serializable resources*. Serializable resources encapsulate your domain objects
(which can be any kind of objects) and present them in a suitable way for JSON
API serialization. They are defined via an intuitive yet extensive DSL.
(which can be any kind of objects -- `ActiveRecord`s, POROs, etc.) and present
them in a suitable way for JSON API serialization. They are defined via an
intuitive yet extensive DSL. In other libraries, serializable resources are
usually called "serializers".

Once your serializable resources are defined, you can pass your business objects
to the *renderer*, that will build the appropriate serializable resources, and
Expand Down
Loading