JSONAPI.View behaviour (jsonapi v1.8.4)
View SourceA View is simply a module that defines certain callbacks to configure proper rendering of your JSONAPI documents.
defmodule PostView do
use JSONAPI.View
def fields, do: [:id, :text, :body]
def type, do: "post"
def relationships do
[author: UserView,
comments: CommentView]
end
end
defmodule UserView do
use JSONAPI.View
def fields, do: [:id, :username]
def type, do: "user"
def relationships, do: []
end
defmodule CommentView do
use JSONAPI.View
def fields, do: [:id, :text]
def type, do: "comment"
def relationships do
[user: {UserView, :include}]
end
end
defmodule DogView do
use JSONAPI.View, namespace: "/pupperz-api"
endYou can now call UserView.show(user, conn, conn.params) and it will render
a valid jsonapi doc.
Fields
By default, the resulting JSON document consists of fields, defined in the fields/0
function. You can define custom fields or override current fields by defining a
2-arity function inside the view that takes data and conn as arguments and has
the same name as the field it will be producing. Refer to our fullname/2 example below.
defmodule UserView do
use JSONAPI.View
def fullname(data, conn), do: "fullname"
def fields, do: [:id, :username, :fullname]
def type, do: "user"
def relationships, do: []
endFields may be omitted manually using the hidden/1 function.
defmodule UserView do
use JSONAPI.View
def fields, do: [:id, :username, :email]
def type, do: "user"
def hidden(_data) do
[:email] # will be removed from the response
end
endIn order to use sparse fieldsets
you must include the JSONAPI.QueryParser plug.
If you want to fetch fields from the given data dynamically, you can use the
get_field/3 callback.
defmodule UserView do
use JSONAPI.View
def fields, do: [:id, :username, :email]
def type, do: "user"
def get_field(field, data, _conn) do
Map.fetch!(data, field)
end
endRelationships
Currently the relationships callback expects that a map is returned configuring the information you will need. If you have the following Ecto Model setup
defmodule User do
schema "users" do
field :username
has_many :posts
has_one :image
end
endand the includes setup from above. If your Post has loaded the author and the query asks for it then it will be loaded.
So for example:
GET /posts?include=post.author if the author record is loaded on the Post, and you are using
the JSONAPI.QueryParser it will be included in the includes section of the JSONAPI document.
If you always want to include a relationship. First make sure its always preloaded
and then use the [user: {UserView, :include}] syntax in your includes function. This tells
the serializer to always include if its loaded.
Options
:host(binary) - Allows thehostto be overridden for generated URLs. Defaults tohostof the suppliedconn.:scheme(atom) - Enables configuration of the HTTP scheme for generated URLS. Defaults toschemefrom the providedconn.:namespace(binary) - Allows the namespace of a given resource. This may be configured globally or overridden on the View itself. Note that if you have a globally defined namespace and need to remove the namespace for a resource, set the namespace to a blank String.
The default behaviour for host and scheme is to derive it from the conn provided, while the
default style for presentation in names is to be underscored and not dashed.
Summary
Types
Callbacks
@callback attributes(data(), Plug.Conn.t() | nil) :: map()
@callback fields() :: [field()]
@callback get_field(field(), data(), Plug.Conn.t()) :: any()
@callback id(data()) :: resource_id() | nil
@callback links(data(), Plug.Conn.t()) :: links()
@callback meta(data(), Plug.Conn.t()) :: meta() | nil
@callback namespace() :: String.t()
@callback pagination_links( data(), Plug.Conn.t(), JSONAPI.Paginator.page(), JSONAPI.Paginator.options() ) :: JSONAPI.Paginator.links()
@callback path() :: String.t() | nil
@callback type() :: resource_type()
@callback url_for(data(), Plug.Conn.t() | nil) :: String.t()
@callback url_for_pagination(data(), Plug.Conn.t(), JSONAPI.Paginator.params()) :: String.t()
@callback url_for_rel(term(), String.t(), Plug.Conn.t() | nil) :: String.t()
@callback visible_fields(data(), Plug.Conn.t() | nil) :: [atom()]
Functions
@spec url_for(t(), term(), Plug.Conn.t() | nil) :: String.t()
@spec url_for_rel(t(), data(), resource_type(), Plug.Conn.t() | nil) :: String.t()
@spec url_for_rel(t(), data(), Plug.Conn.query_params(), JSONAPI.Paginator.params()) :: String.t()
@spec visible_fields(t(), data(), Plug.Conn.t() | nil) :: [atom()]