View Source JSONAPIPlug.Resource behaviour (jsonapi_plug v1.0.6)
A Resource is simply a module that describes how to render your data as JSON:API resources.
You can implement a resource by "use-ing" the JSONAPIPlug.Resource
module, which is recommeded, or
by adopting the JSONAPIPlug.Resource
behaviour and implementing all of the callback functions:
defmodule MyApp.UsersResource do
use JSONAPIPlug.Resource,
type: "user",
attributes: [:name, :surname, :username]
end
See options/0
for all available options you can pass to use JSONAPIPlug.Resource
.
You can now call UsersResource.render("show.json", %{data: user})
or Resource.render(UsersResource, conn, user)
to render a valid JSON:API document from your data. If you use phoenix, you can use:
render(conn, "show.json", %{data: user})
in your controller functions to render the document in the same way.
Attributes
By default, the resulting JSON document consists of resources taken from your data. Only resource attributes defined on the resource will be (de)serialized. You can customize how attributes are handled by passing a keyword list of options:
defmodule MyApp.UsersResource do
use JSONAPIPlug.Resource,
type: "user",
attributes: [
username: nil,
fullname: [deserialize: false, serialize: &fullname/2]
]
defp fullname(resource, conn), do: "#{resouce.first_name} #{resource.last_name}"
end
In this example we are defining a computed attribute by passing the serialize
option a function reference.
Serialization functions take resource
and conn
as arguments and return the attribute value to be serialized.
The deserialize
option set to false
makes sure the attribute is not deserialized when receiving a request.
Relationships
Relationships are defined by passing the relationships
option to use JSONAPIPlug.Resource
.
defmodule MyApp.PostResource do
use JSONAPIPlug.Resource,
type: "post",
attributes: [:text, :body]
relationships: [
author: [resource: MyApp.UsersResource],
comments: [many: true, resource: MyApp.CommentsResource]
]
end
defmodule MyApp.CommentsResource do
alias MyApp.UsersResource
use JSONAPIPlug.Resource,
type: "comment",
attributes: [:text]
relationships: [post: [resource: MyApp.PostResource]]
end
When requesting GET /posts?include=author
, if the author key is present on the data you pass from the
controller it will appear in the included
section of the JSON:API response.
Links
When rendering resource links, the default behaviour is to is to derive values for host
, port
and scheme
from the connection. If you need to use different values for some reason, you can override them
using JSONAPIPlug.API
configuration options in your api configuration:
config :my_app, MyApp.API, host: "adifferenthost.com"
Summary
Types
Attribute options
Resource attributes
Resource data
Resource field name
Resource meta
Resource options
Relationship options
Resource attributes
Resource data
Resource module
Callbacks
Resource attributes
Resource Id Attribute
Resource links
Resource meta
Resource normalizer
Resource path
Resource function to recase fields
Resource relationships
Resource Type
Functions
Field option
Field option
Related Resource based on JSON:API type
Render JSON:API response
Generates the resource link
Generate relationships link
Types
@type attribute_options() :: [ name: field_name(), serialize: boolean() | (resource(), Plug.Conn.t() -> term()), deserialize: boolean() | (resource(), Plug.Conn.t() -> term()) ]
Attribute options
:name
(atom/0
) - Maps the resource attribute name to the given key.:serialize
- Can be either a boolean, a function reference or MFA returning the attribute value to be serialized. The default value istrue
.:deserialize
- Can be either a boolean, a function reference or MFA returning the attribute value to be deserialized. The default value istrue
.
@type attributes() :: [field_name()] | [{field_name(), attribute_options()}]
Resource attributes
A keyword list composed of attribute names and their options
Resource data
Resource data is either a resource or a list of resources
@type field() :: field_name() | {field_name(), attribute_options() | relationship_options()}
@type field_name() :: atom()
Resource field name
The name of a Resource field (attribute or relationship)
@type meta() :: JSONAPIPlug.Document.meta()
Resource meta
A free form map containing metadata to be rendered
@type options() :: keyword()
Resource options
:attributes
- Resource attributes. This will be used to (de)serialize requests/responses::name
(atom/0
) - Maps the resource attribute name to the given key.:serialize
- Can be either a boolean, a function reference or MFA returning the attribute value to be serialized. The default value istrue
.:deserialize
- Can be either a boolean, a function reference or MFA returning the attribute value to be deserialized. The default value istrue
.
The default value is
[]
.:id_attribute
(atom/0
) - Attribute on your data to be used as the JSON:API resource id. The default value is:id
.:path
(String.t/0
) - A custom path to be used for the resource. Defaults to the resource type.:relationships
(keyword/0
) - Resource relationships. This will be used to (de)serialize requests/responses The default value is[]
.:type
(String.t/0
) - Required. Resource type. To be used as the JSON:API resource type value
@type relationship_options() :: [many: boolean(), name: field_name(), resource: t()]
Relationship options
@type relationships() :: [{field_name(), relationship_options()}]
Resource attributes
A keyword list composed of relationship names and their options
@type resource() :: term()
Resource data
User data representing a single resource
@type t() :: module()
Resource module
A Module adopting the JSONAPIPlug.Resource
behaviour
Callbacks
@callback attributes() :: attributes()
Resource attributes
Returns the keyword list of resource attributes for the resource.
@callback id_attribute() :: field_name()
Resource Id Attribute
Returns the attribute used to fetch resource ids for resources by the resource.
@callback links(resource(), Plug.Conn.t() | nil) :: JSONAPIPlug.Document.links()
Resource links
Returns the resource links to be returned for resources by the resource.
@callback meta(resource(), Plug.Conn.t() | nil) :: JSONAPIPlug.Document.meta()
Resource meta
Returns the resource meta to be returned for resources by the resource.
@callback normalizer() :: JSONAPIPlug.Normalizer.t()
Resource normalizer
Returns the resource normalizer for resources by the resource.
@callback path() :: String.t() | nil
Resource path
Returns the path to prepend to resources for the resource.
@callback recase_field(field_name(), JSONAPIPlug.case()) :: String.t()
Resource function to recase fields
Returns the field is the required case
@callback relationships() :: relationships()
Resource relationships
Returns the keyword list of resource relationships for the resource.
@callback type() :: JSONAPIPlug.Document.ResourceObject.type()
Resource Type
Returns the Resource Type of resources for the resource.
Functions
@spec field_name(field()) :: field_name()
Field option
Returns the name of the attribute or relationship for the field definition.
Field option
Returns the value of the attribute or relationship option for the field definition.
@spec render( t(), Plug.Conn.t(), data() | nil, JSONAPIPlug.Document.meta() | nil, options() ) :: JSONAPIPlug.Document.t() | no_return()
Render JSON:API response
Renders the JSON:API response for the specified Resource.
@spec url_for(t(), data(), Plug.Conn.t() | nil) :: String.t()
Generates the resource link
Generates the resource link for a resource.
@spec url_for_relationship( t(), resource(), Plug.Conn.t() | nil, JSONAPIPlug.Document.ResourceObject.type() ) :: String.t()
Generate relationships link
Generates the relationships link for a resource.