JaSerializer.Serializer
Define a serialization schema.
Provides serialize/2
, has_many/2
, has_one/2
, attributes1
and
location1
macros to define how your model (struct or map) will be rendered
in the JSONAPI.org 1.0 format.
Defines format/1
, format/2
and format/3
used to convert models (and
list of models) for encoding in your JSON library of choice.
Example
defmodule PostSerializer do
use JaSerializer
serialize "posts" do
location "/posts/:id"
attributes [:title, :body, :excerpt, :tags]
has_many :comments,
link: "/posts/:id/comments",
has_one :author,
include: PersonSerializer
end
def excerpt(post, _conn) do
[first | _ ] = String.split(post.body, ".")
first
end
end
post = %Post{
id: 1,
title: "jsonapi.org + Elixir = Awesome APIs",
body: "so. much. awesome.",
author: %Person{name: "Alan"}
}
post
|> PostSerializer.format
|> Poison.encode!
Summary↑
attributes(atts) | Defines a list of attributes to be included in the payload |
has_many(name, opts \\ []) | Add a has_many relationship to be serialized |
has_one(name, opts \\ []) | See documentation for has_many/2 |
location(uri) | Defines the canoical path for retrieving this resource |
serialize(type, list2) | Define a serialization schema |
Macros
Defines a list of attributes to be included in the payload.
An overrideable function for each attribute is generated with the same name as the attribute. The function’s default behavior is to retrieve a field with the same name from the model.
For example, if you have attributes [:body]
a function body/2
is defined
on the serializer with a default behavior of Map.get(model, :body)
.
Add a has_many relationship to be serialized.
Relationships may be included in any of three composeable ways:
- Links
- Resource Identifiers
- Includes
Relationship Source
When you define a relationship, a function is defined of the same name in the
serializer module. This function is overrideable but by default attempts to
access a field of the same name as the relationship on the map/struct passed
in. The field may be changed using the field
option.
For example if you have_many :comments
a function comments2
is defined
which calls Dict.get(model, :comments)
by default.
Link based relationships
Specify a uri which responds with the related resources. See location/1 for defining uris.
The relationship source is disregarded when linking.
defmodule PostSerializer do
use JaSerializer
serialize "posts" do
has_many :comments, link: "/posts/:id/comments"
end
end
Resource Identifier Relationships
Adds a list of id
and type
pairs to the response with the assumption the
API consumer can use them to retrieve the related resources as needed.
The relationship source should return either a list of ids or maps/structs
that have an id
field.
defmodule PostSerializer do
use JaSerializer
serialize "posts" do
has_many :comments, type: "comments"
end
def comments(post, _conn) do
post |> PostModel.get_comments |> Enum.map(&(&1.id))
end
end
Included Relationships
Adds a list of id
and type
pairs, just like Resource Indentifier
relationships, but also adds the full serialized resource to the response to
be “sideloaded” as well.
The relationship source should return a list of maps/structs.
WARNING: Currently sideloaded resources do not have thier own included resources included.
defmodule PostSerializer do
use JaSerializer
serialize "posts" do
has_many :comments, include: CommentSerializer
end
def comments(post, _conn) do
post |> PostModel.get_comments
end
end
defmodule CommentSerializer do
use JaSerializer
serialize "comments" do
has_one :post, field: :post_id, type: "posts"
attributes [:body]
end
end
See documentation for has_many/2.
API is the exact same.
Defines the canoical path for retrieving this resource.
String Examples
String may be either a full url or a relative path. Path segments begining with a colin are called as functions on the serializer with the model and conn passed in.
defmodule PostSerializer do
use JaSerializer
serialize "posts" do
location "/posts/:id"
end
end
defmodule CommentSerializer do
use JaSerializer
serialize "comment" do
location "http://api.example.com/posts/:post_id/comments/:id"
end
def post_id(comment, _conn), do: comment.post_id
end
Atom Example
When an atom is passed in it is assumed it is a function that will return a relative or absolute path.
defmodule PostSerializer do
use JaSerializer
import MyPhoenixApp.Router.Helpers
serialize "post" do
location :post_url
end
def post_url(post, conn) do
#TODO: Verify conn can be used here instead of Endpoint
post_path(conn, :show, post.id)
end
end
Define a serialization schema.
The type
should be the plural version of the type of object being
serialized. This maps to the JSONAPI type field.
Defines an overridable id
function that is expected to return the id of the
object being serialized. Defaults to Map.get(model, :id)
.
Example
defmodule PostSerializer do
use JaSerializer
serialize "posts" do
# JaSerializer.Serialization macros available here.
end
# Optional override
def id(post, conn) do
post.id
end
end