I’m wondering how do people structure their JSON Api’s with Phoenix. Using the blogs example, let’s say I have a blogs view like the following
def render("show.json", %{blog: blog}) do
%{
id: blog.id,
title: blog.title,
posts: render_many(blog.posts, PostView, "post.json")
}
This runs into things like what if posts has its own associations like comments, etc.
In my controller maybe sometimes I don’t care about the associations and other times I do. This leads me to two main problems?
- Are there any standards people follow to handle when a view should try and render associations?
- Should there be some helper function in Phoenix.View that handles conditionally rendering associations?
For the first problem I’m just curious how people do something like the following
def show(conn, %{"id" => id}) do
blog = Blogs.get_blog_with_all(id)
# assume no associations are preloaded
render(conn, "show.json", blog: blog)
end
def some_action(conn, %{"id" => id}) do
blog = Blogs.get_blog_with_all(id, preload: [:association_one, :association_two])
# here I want to include the two associations in my view
render(conn, "show_with_association_one_and_two.json", blog: blog)
end
Having a specific view for each combination of association seems tedious.
For the second problem I mean something like having a helper function maybe_render_association
that will add the field to the view if the association is loaded or it will not include the field at all. My thinking is we don’t want to return nil
in the case that the association is not loaded since it’s not actually nil. That pattern would look like
def render() do
def render("post.json", %{post: post}) do
%{
id: post.id,
title: post.title,
body: post.body,
comments: render_many(post.comments, CommentView, "comment.json")
}
# it would be nice if we can have it inside the above map but
# since it's a conditional field not sure how
|> maybe_render_association(post.updated_by, :updated_by, User, "basic.json")
end
end