View Source JSONAPIPlug.Resource behaviour (jsonapi_plug v1.0.5)

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.

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

t()

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

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 - Controls attribute serialization. Can be either a boolean (do/don't serialize) or a function reference returning the attribute value to be serialized for full control. The default value is true.

  • :deserialize - Controls attribute deserialization. Can be either a boolean (do/don't deserialize) or a function reference returning the attribute value to be deserialized for full control. The default value is true.

@type attributes() :: [field_name()] | [{field_name(), attribute_options()}]

Resource attributes

A keyword list composed of attribute names and their options

@type data() :: resource() | [resource()]

Resource data

Resource data is either a resource or a list of resources

@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 - Controls attribute serialization. Can be either a boolean (do/don't serialize) or a function reference returning the attribute value to be serialized for full control. The default value is true.

    • :deserialize - Controls attribute deserialization. Can be either a boolean (do/don't deserialize) or a function reference returning the attribute value to be deserialized for full control. The default value is true.

    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 [].

    • :name (atom/0) - Maps the resource relationship name to the given key.

    • :many (boolean/0) - Specifies a to many relationship. The default value is false.

    • :resource (atom/0) - Required. Specifies the resource to be used to serialize the relationship

  • :type (String.t/0) - Required. Resource type. To be used as the JSON:API resource type value

Link to this type

relationship_options()

View Source
@type relationship_options() :: [many: boolean(), name: field_name(), resource: t()]

Relationship options

  • :name (atom/0) - Maps the resource relationship name to the given key.

  • :many (boolean/0) - Specifies a to many relationship. The default value is false.

  • :resource (atom/0) - Required. Specifies the resource to be used to serialize the relationship

@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.

Link to this callback

recase_field(field_name, case)

View Source
@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.

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.

Link to this function

field_option(name, option)

View Source
@spec field_option(field(), atom()) :: term()

Field option

Returns the value of the attribute or relationship option for the field definition.

Link to this function

field_option(field, option, default)

View Source
Link to this function

render(resource, conn, data \\ nil, meta \\ nil, options \\ [])

View Source
@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.

Link to this function

url_for(resource, data, conn)

View Source
@spec url_for(t(), data(), Plug.Conn.t() | nil) :: String.t()

Generates the resource link

Generates the resource link for a resource.

Link to this function

url_for_relationship(resource, data, conn, relationship_type)

View Source
@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.