Elixir phoenix — Render Ecto schema to json with relationships

Dzung Nguyen
2 min readJul 31, 2021

When writing API with Phoenix and render json to client,

  • For some fields I want to keep it original value.
  • For some fields, I want to do some calculation or format data before returning.
  • And I want to render Ecto association too.

An while working on an project at OnPoint I have build a little module that helps to do this easier.

I have extract that module and release as a package named JsonView. Its source code is hosted on github:

https://github.com/bluzky/json_view

You can use it with Phoenix.View or use it independently. It helps to manipulate data, and handle rendering association automatically.

I have published an article on how to write it
A better way to render json response in Elixir Phoenix

Let’s take a look.

First define view modules

defmodule MyApp.UserView do
use JsonView
def render("user.json", %{user: user}) do
render_json(user, [:first_name, :last_name, :vatar], [], [])
end
end
defmodule MyApp.PostView do
use JsonView
# define which fields return without modifying
@fields [:title, :content, :excerpt, :cover]
# define which fields that need to format or calculate, you have to define `render_field/2` below
@custom_fields [:like_count]
# define which view used to render relationship
@relationships [author: MyApp.UserView]
def render("post.json", %{post: post}) do
# 1st way if `use JsonView`
render_json(post, @fields, @custom_fields, @relationships)
end
def render_field(:like_count, item) do
# load like_count from some where
end
end

And then use it

post = %Post{
title: "Hello JsonView",
excerpt: "Now you can render Json easier",
content: "Install and put it to work",
cover: nil,
inserted_at: ~N[2021-07-05 00:00:00],
updated_at: ~N[2021-07-09 00:00:00],
author: %User{
first_name: "Daniel",
last_name: "James",
email: "daniel@example.com",
avatar: nil,
inserted_at: ~N[2021-06-30 00:00:00]
updated_at: ~N[2021-07-02 00:00:00]
}
}
MyApp.PostView.render("post.json", %{post: post})# or invoke from PostController
render(conn, "post.json", post: post)

This is the result that you can use to return from PhoenixController

%{
title: "Hello JsonView",
excerpt: "Now you can render Json easier",
content: "Install and put it to work",
cover: nil,
like_count: nil,
author: %{
first_name: "Daniel",
last_name: "James"
}
}

If you have any feedback, please comment or create an issue.

In the next post I will go through step by step to write this library.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Dzung Nguyen
Dzung Nguyen

Written by Dzung Nguyen

I'm a full-stack web developer that are so lazy to code to much so I have to learn to do it the smart way.

No responses yet

Write a response