Serializable resources are defined by subclassing
JSONAPI::Serializable::Resource
and using its DSL.
Example:
class SerializablePost < JSONAPI::Serializable::Resource
type 'posts'
attributes :title, :body
attribute :date do
@object.created_at
end
belongs_to :author
has_many :comments do
data do
@object.published_comments
end
link :related do
@url_helpers.user_posts_url(@object.id)
end
meta do
{ count: @object.published_comments.count }
end
end
link :self do
@url_helpers.post_url(@object.id)
end
meta do
{ featured: true }
end
end
The principle is simple: you declare elements of the JSON API resource and 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 via the expose
option - are available throughout the DSL
as instance variables.)
The type
property is declared via the DSL method of the same name, and takes
a symbol, a string, or a block.
Examples:
class SerializablePost < JSONAPI::Serializable::Resource
type 'posts'
end
class SerializablePost < JSONAPI::Serializable::Resource
type { @object.type }
end
The id
property is declared via the DSL method of the same name, and takes a
block. If no id is explicitly declared, it will default to @object.id
.
Example:
class SerializablePost < JSONAPI::Serializable::Resource
# ...
id { @object.uuid }
end
Attributes are declared either via the attribute
(singular) or attributes
(plural) DSL methods. The former allows to specify an explicit value for the
attribute (if a block is provided), whereas the latter only allows implicit
definition of the values (they will be determined by calling methods named
after the attributes on the underlying object).
Example:
class SerializablePost < JSONAPI::Serializable::Resource
# ...
attribute :date # This will have value @object.date
class SerializablePost < JSONAPI::Serializable::Resource
# ...
attribute :date do
@object.created_at
end
attributes :title, :content
end
Meta information can be declared via the meta
DSL method. The value can either
be set directly as a hash:
class SerializablePost < JSONAPI::Serializable::Resource
# ...
meta foo: 'bar'
end
or dynamically in a block (in case it needs access to the exposures):
class SerializablePost < JSONAPI::Serializable::Resource
# ...
meta do
{ foo: @object.foo }
end
end
Links are declared via the link
DSL method. The value can either be set
directly as a string:
class SerializablePost < JSONAPI::Serializable::Resource
# ...
link :self do
"http://api.example.com/posts/#{@object.id}"
end
end
or built via the href
and meta
DSL methods:
class SerializablePost < JSONAPI::Serializable::Resource
# ...
link :self do
href "http://api.example.com/posts/#{@object.id}"
meta public: true
end
end
Relationships are declared via the has_many
, has_one
and belongs_to
DSL
methods. belongs_to
is actually an alias for has_one
, and you can use both
interchangeably.
The shortest way to declare an association is simply:
class SerializablePost < JSONAPI::Serializable::Resource
# ...
has_many :comments
end
This will set the value of the relationship by calling the method of the same name on the underlying object.
It is also possible to explicitly define the value of a relationship via the
data
DSL method.
Example:
class SerializablePost < JSONAPI::Serializable::Resource
# ...
has_many :comments do
data do
@object.published_comments
end
end
end
Moreover, it is possible to declare links and meta informations inside a
relationship via the meta
and link
DSL methods, the same way as for
resource-level links and meta information.
Example:
class SerializablePost < JSONAPI::Serializable::Resource
# ...
has_many :comments do
link :self do
"http://api.example.com/posts/#{@object.id}/relationships/comments"
end
meta foo: 'bar'
end
end
By default, for an instance of class Post
, the corresponding serializable
resource class will be assumed to be SerializablePost
(this behavior can be
configured, see next section).
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.