Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove all references to anything Pagination related #321

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions lib/jsonapi/paginator.ex

This file was deleted.

56 changes: 11 additions & 45 deletions lib/jsonapi/serializer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ defmodule JSONAPI.Serializer do
encoded_data
end

merge_links(encoded_data, data, view, conn, query_page, remove_links?(), options)
custom_merge_links(encoded_data, view.links(data, conn, query_page))
end

def encode_data(_view, nil, _conn, _query_includes, _options), do: {[], nil}
Expand All @@ -65,12 +65,10 @@ defmodule JSONAPI.Serializer do
relationships: %{}
}

doc = merge_links(encoded_data, data, view, conn, nil, remove_links?(), options)

doc =
case view.meta(data, conn) do
nil -> doc
meta -> Map.put(doc, :meta, meta)
nil -> encoded_data
meta -> Map.put(encoded_data, :meta, meta)
end

encode_relationships(conn, doc, {view, data, query_includes, valid_includes}, options)
Expand All @@ -89,7 +87,7 @@ defmodule JSONAPI.Serializer do
tuple()
def build_relationships(
conn,
{parent_view, parent_data, query_includes, valid_includes},
{_parent_view, _parent_data, query_includes, valid_includes},
relationship_name,
rel_data,
rel_view,
Expand All @@ -98,8 +96,8 @@ defmodule JSONAPI.Serializer do
) do
# Build the relationship url
rel_key = transform_fields(relationship_name)
rel_url = parent_view.url_for_rel(parent_data, rel_key, conn)

# rel_url = parent_view.url_for_rel(parent_data, rel_key, conn)
rel_url = nil
# Build the relationship
acc =
put_in(
Expand Down Expand Up @@ -199,48 +197,18 @@ defmodule JSONAPI.Serializer do
end

@spec encode_relation(tuple()) :: map()
def encode_relation({rel_view, rel_data, _rel_url, _conn} = info) do
data = %{
def encode_relation({rel_view, rel_data, _rel_url, _conn}) do
%{
data: encode_rel_data(rel_view, rel_data)
}

merge_related_links(data, info, remove_links?())
end

defp merge_base_links(%{links: links} = doc, data, view, conn) do
view_links = Map.merge(view.links(data, conn), links)
Map.merge(doc, %{links: view_links})
end

defp merge_links(doc, data, view, conn, page, false, options) when is_list(data) do
links =
Map.merge(view.pagination_links(data, conn, page, options), %{
self: view.url_for_pagination(data, conn, page)
})
def custom_merge_links(encoded_data, nil), do: encoded_data

doc
|> Map.merge(%{links: links})
|> merge_base_links(data, view, conn)
def custom_merge_links(encoded_data, links) do
Map.merge(encoded_data, %{links: links})
end

defp merge_links(doc, data, view, conn, _page, false, _options) do
doc
|> Map.merge(%{links: %{self: view.url_for(data, conn)}})
|> merge_base_links(data, view, conn)
end

defp merge_links(doc, _data, _view, _conn, _page, _remove_links, _options), do: doc

defp merge_related_links(
encoded_data,
{rel_view, rel_data, rel_url, conn},
false = _remove_links
) do
Map.merge(encoded_data, %{links: %{self: rel_url, related: rel_view.url_for(rel_data, conn)}})
end

defp merge_related_links(encoded_rel_data, _info, _remove_links), do: encoded_rel_data

@spec encode_rel_data(module(), map() | list()) :: map() | nil
def encode_rel_data(_view, nil), do: nil

Expand Down Expand Up @@ -296,8 +264,6 @@ defmodule JSONAPI.Serializer do
|> List.flatten()
end

defp remove_links?, do: Application.get_env(:jsonapi, :remove_links, false)

defp transform_fields(fields) do
case Utils.String.field_transformation() do
:camelize -> Utils.String.expand_fields(fields, &Utils.String.camelize/1)
Expand Down
146 changes: 4 additions & 142 deletions lib/jsonapi/view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ defmodule JSONAPI.View do
end

defmodule DogView do
use JSONAPI.View, namespace: "/pupperz-api"
use JSONAPI.View
end

You can now call `UserView.show(user, conn, conn.params)` and it will render
Expand Down Expand Up @@ -112,22 +112,8 @@ defmodule JSONAPI.View do
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 the `host` to be overridden for generated URLs. Defaults to `host` of the supplied `conn`.

* `:scheme` (atom) - Enables configuration of the HTTP scheme for generated URLS. Defaults to `scheme` from the provided `conn`.

* `: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.
"""

alias JSONAPI.{Paginator, Utils}
alias Plug.Conn

@type t :: module()
Expand All @@ -144,38 +130,25 @@ defmodule JSONAPI.View do
@callback fields() :: [field()]
@callback get_field(field(), data(), Conn.t()) :: any()
@callback hidden(data()) :: [field()]
@callback links(data(), Conn.t()) :: links()
@callback links(data(), Conn.t(), map() | nil) :: links() | nil
@callback meta(data(), Conn.t()) :: meta() | nil
@callback namespace() :: String.t()
@callback pagination_links(data(), Conn.t(), Paginator.page(), Paginator.options()) ::
Paginator.links()
@callback path() :: String.t() | nil
@callback relationships() :: [
{atom(), t() | {t(), :include} | {atom(), t()} | {atom(), t(), :include}}
]
@callback type() :: resource_type()
@callback url_for(data(), Conn.t() | nil) :: String.t()
@callback url_for_pagination(data(), Conn.t(), Paginator.params()) :: String.t()
@callback url_for_rel(term(), String.t(), Conn.t() | nil) :: String.t()
@callback visible_fields(data(), Conn.t() | nil) :: list(atom)

@optional_callbacks [get_field: 3]

defmacro __using__(opts \\ []) do
{type, opts} = Keyword.pop(opts, :type)
{namespace, opts} = Keyword.pop(opts, :namespace)
{path, opts} = Keyword.pop(opts, :path)
{paginator, _opts} = Keyword.pop(opts, :paginator)
{type, _opts} = Keyword.pop(opts, :type)

quote do
alias JSONAPI.{Serializer, View}

@behaviour View

@resource_type unquote(type)
@namespace unquote(namespace)
@path unquote(path)
@paginator unquote(paginator)

@impl View
def id(nil), do: nil
Expand Down Expand Up @@ -210,32 +183,11 @@ defmodule JSONAPI.View do
def hidden(_data), do: []

@impl View
def links(_data, _conn), do: %{}
def links(_data, _conn, _query_page), do: nil

@impl View
def meta(_data, _conn), do: nil

@impl View
if @namespace do
def namespace, do: @namespace
else
def namespace, do: Application.get_env(:jsonapi, :namespace, "")
end

@impl View
def pagination_links(data, conn, page, options) do
paginator = Application.get_env(:jsonapi, :paginator, @paginator)

if Code.ensure_loaded?(paginator) && function_exported?(paginator, :paginate, 5) do
paginator.paginate(data, __MODULE__, conn, page, options)
else
%{}
end
end

@impl View
def path, do: @path

@impl View
def relationships, do: []

Expand All @@ -246,18 +198,6 @@ defmodule JSONAPI.View do
def type, do: raise("Need to implement type/0")
end

@impl View
def url_for(data, conn),
do: View.url_for(__MODULE__, data, conn)

@impl View
def url_for_pagination(data, conn, pagination_params),
do: View.url_for_pagination(__MODULE__, data, conn, pagination_params)

@impl View
def url_for_rel(data, rel_type, conn),
do: View.url_for_rel(__MODULE__, data, rel_type, conn)

@impl View
def visible_fields(data, conn),
do: View.visible_fields(__MODULE__, data, conn)
Expand Down Expand Up @@ -296,60 +236,6 @@ defmodule JSONAPI.View do
end
end

@spec url_for(t(), term(), Conn.t() | nil) :: String.t()
def url_for(view, data, nil = _conn) when is_nil(data) or is_list(data),
do: URI.to_string(%URI{path: Enum.join([view.namespace(), path_for(view)], "/")})

def url_for(view, data, nil = _conn) do
URI.to_string(%URI{
path: Enum.join([view.namespace(), path_for(view), view.id(data)], "/")
})
end

def url_for(view, data, %Plug.Conn{} = conn) when is_nil(data) or is_list(data) do
URI.to_string(%URI{
scheme: scheme(conn),
host: host(conn),
port: port(conn),
path: Enum.join([view.namespace(), path_for(view)], "/")
})
end

def url_for(view, data, %Plug.Conn{} = conn) do
URI.to_string(%URI{
scheme: scheme(conn),
host: host(conn),
port: port(conn),
path: Enum.join([view.namespace(), path_for(view), view.id(data)], "/")
})
end

@spec url_for_rel(t(), data(), resource_type(), Conn.t() | nil) :: String.t()
def url_for_rel(view, data, rel_type, conn) do
"#{url_for(view, data, conn)}/relationships/#{rel_type}"
end

@spec url_for_rel(t(), data(), Conn.query_params(), Paginator.params()) :: String.t()
def url_for_pagination(
view,
data,
%{query_params: query_params} = conn,
nil = _pagination_params
) do
query =
query_params
|> Utils.List.to_list_of_query_string_components()
|> URI.encode_query()

prepare_url(view, query, data, conn)
end

def url_for_pagination(view, data, %{query_params: query_params} = conn, pagination_params) do
query_params = Map.put(query_params, "page", pagination_params)

url_for_pagination(view, data, %{conn | query_params: query_params}, nil)
end

@spec visible_fields(t(), data(), Conn.t() | nil) :: list(atom)
def visible_fields(view, data, conn) do
all_fields =
Expand All @@ -372,33 +258,9 @@ defmodule JSONAPI.View do
|> MapSet.to_list()
end

defp prepare_url(view, "", data, conn), do: url_for(view, data, conn)

defp prepare_url(view, query, data, conn) do
view
|> url_for(data, conn)
|> URI.parse()
|> struct(query: query)
|> URI.to_string()
end

defp requested_fields_for_type(view, %Conn{assigns: %{jsonapi_query: %{fields: fields}}}) do
fields[view.type()]
end

defp requested_fields_for_type(_view, _conn), do: nil

defp host(%Conn{host: host}),
do: Application.get_env(:jsonapi, :host, host)

defp port(%Conn{port: 0} = conn),
do: port(%{conn | port: URI.default_port(scheme(conn))})

defp port(%Conn{port: port}),
do: Application.get_env(:jsonapi, :port, port)

defp scheme(%Conn{scheme: scheme}),
do: Application.get_env(:jsonapi, :scheme, to_string(scheme))

defp path_for(view), do: view.path() || view.type()
end
Loading
Loading