Comments (9)
Howdy @fireproofsocks! I'm happy to add a little section like this:
defp deps do
[{:jsonapi, "~> 0.1.0"}]
end
I'm not sure this is the right place for a write up on how to add packages and resolve them.
from jsonapi.
@fireproofsocks @oskarrough this issue is a bit stale, but I wanted to check in to see if you've got what you needed before I closed it.
from jsonapi.
Expanding on this, I am not sure how to use this library with Phoenix 1.3.
For instance, how do you merge the view from the readme with the default generated one?
defmodule HelloWeb.UserView do
use HelloWeb, :view
alias HelloWeb.UserView, as: UserView
def render("index.json", %{users: users}) do
%{data: render_many(users, UserView, "user.json")}
end
def render("show.json", %{user: user}) do
%{data: render_one(user, UserView, "user.json")}
end
def render("user.json", %{user: user}) do
%{id: user.id,
email: user.email,
password: user.password}
end
end
from jsonapi.
@oskarrough the instructions say to add use JSONAPI.View
to the top of your view module and the other methods to the body, have you tried that yet?
from jsonapi.
@doomspork thank you. I did try but can't see any change in the JSON output. I'm new to this and feel like I am missing something obivous. Shouldn't the bottom user.json in the view be changed to something?
# two methods from user controller
def index(conn, _params) do
users = Accounts.list_users()
render(conn, "index.json", users: users)
end
def show(conn, %{"id" => id}) do
user = Accounts.get_user!(id)
render(conn, "show.json", user: user)
end
defmodule HelloWeb.UserView do
use HelloWeb, :view
use JSONAPI.View, type: "users"
alias HelloWeb.UserView, as: UserView
def fields() do
[:email]
end
def render("index.json", %{users: users}) do
%{data: render_many(users, UserView, "user.json")}
end
def render("show.json", %{user: user}) do
%{data: render_one(user, UserView, "user.json")}
end
def render("user.json", %{user: user}) do
%{id: user.id,
email: user.email
}
end
end
from jsonapi.
@oskarrough no worries! The https://github.com/jeregrine/jsonapi#how-to-use-with-phoenix section touches on what needs to occur but perhaps we could expand on it some.
JSON API generates a lot of those functions for you, take a peek here: https://github.com/jeregrine/jsonapi/blob/master/lib/jsonapi/view.ex#L143
If you don't intend to do anything additional to the view before returning it, you can just do this:
defmodule HelloWeb.UserView do
use HelloWeb, :view
use JSONAPI.View, type: "users"
def fields() do
[:email]
end
end
The rest should work as expected.
from jsonapi.
@doomspork aah, I see. Thank you, it works. It was helpful to see the actual code from the JSONAPI.View
.. should have checked that :)
It would be great with an example for queries, sorting and filtering as well. I see that GET /api/users?sort=name
will set conn.assigns.jsonapi_query.sort
to [asc: :name]
and tried the following:
# user controller
plug JSONAPI.QueryParser,
filter: ~w(age),
sort: ~w(created_at email),
view: HelloWeb.UserView
def index(conn, _params) do
sort = conn.assigns.jsonapi_query.sort
render(conn, "index.json", data: Accounts.list_users_sorted(sort))
end
# context
def list_users_sorted(sort) do
Repo.all(User |> order_by(^sort))
end
which works! Is it the right way to do it?
from jsonapi.
@oskarrough that's wonderful news!
That is one way to implement the order by and includes. It's difficult to document given that everyone's application will be setup differently and there's no single "right way".
In a previous project I relied on plugs to handle this, please note this code is incomplete because I don't have time to clean this up enough to share in it's entirety:
defmodule JSONAPI.Includes do
def call(%{method: "POST"} = conn, _), do: conn
def call(%{assigns: %{jsonapi_query: query}, private: %{resource: resource}} = conn, opts) do
repo = Keyword.fetch!(opts, :repo)
resource = repo.preload(resource, normalize_includes(query.includes))
Plug.Conn.put_private(conn, :resource, resource)
end
def call(conn, _), do: conn
defp normalize_include(include) when is_atom(include), do: include
defp normalize_include({}), do: []
defp normalize_include(include) when is_tuple(include) do
parent = elem(include, 0)
children = Tuple.delete_at(include, 0)
Keyword.put([], parent, normalize_include(children))
end
defp normalize_includes(includes), do: Enum.map(includes, &normalize_include/1)
end
defmodule JSONAPI.Query do
def call(%{assigns: %{jsonapi_query: jsonapi_query}} = conn, opts) do
resource = Keyword.get(opts, :resource)
repo = Keyword.fetch!(opts, :repo)
filters = query_filters(jsonapi_query)
resource
|> select([r], r)
|> order_by([r], ^jsonapi_query.sort)
|> build_query(filters)
|> repo.all
|> handle_results(conn)
end
def call(conn, _opts) do
conn
end
defp build_query(query, filters) when is_list(filters), do: Enum.reduce(filters, query, &build_query/2)
defp build_query({k, v}, query) when is_list(v), do: where(query, [r], field(r, ^k) in ^v)
defp build_query({k, v}, query), do: where(query, [r], field(r, ^k) == ^v)
defp query_filters(%{filter: filters}), do: Enum.map(filters, &query_filter/1)
defp query_filter({k, v}) when is_binary(v) do
value =
case String.split(v, ",") do
[one] -> one
list -> list
end
{k, value}
end
defp query_filter(filter), do: filter
end
from jsonapi.
Thanks @jherdman I think we're good! Thanks for checking!
from jsonapi.
Related Issues (20)
- UnderscoreParameters plug underscore filters only in params map and not in jsonapi_query assign. HOT 2
- UnderscoreParameters behaviour with GET requests HOT 6
- Migrating to BEAM Community org HOT 15
- Bug with expected format in `included` data HOT 2
- Add GitHub Actions workflow for Hex package releases HOT 3
- Extensions and `lid` HOT 1
- Dynamic fields in views HOT 3
- Publish New Version on Hex HOT 3
- Empty one-to-one relationship incorrectly surfaced (should be surfaced as null) HOT 5
- The url_for_pagination function throws an error when supplied a nested filter HOT 1
- Replace query params as default HOT 1
- Standardize on underscoring query parameters HOT 2
- (FunctionClauseError) no function clause matching in JSONAPI.Utils.DataToParams.transform_relationship/2 HOT 3
- [Feature] Allow For Exclusion of Optional Resource Members HOT 5
- Allow conditionally hidden fields HOT 2
- Bug: Relationship keys not transformed with `dasherize_shallow` config option
- Incorrect InvalidQuery Errors Caused by `String.to_existing_atom/1` HOT 2
- Paginating Relationships HOT 1
- Assertion for tests HOT 1
- JSONAPI.ContentTypeNegotiation ignore some methods for validation HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jsonapi.