Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make Phoenix Controller to output pretty JSON

Is there a way to make Phoenix.Controller.json(conn, data) to output pretty JSON?

like image 961
Alex Craft Avatar asked Jul 09 '16 04:07

Alex Craft


1 Answers

Phoenix.Controller.json/2 currently does not accept options that could be passed to the JSON encoder.

If you want to globally make all json calls output pretty JSON, you can create a wrapper around Poison and tell Phoenix to use it.

In lib/my_app/pretty_poison_encoder_for_phoenix.ex, add:

defmodule MyApp.PrettyPoisonEncoderForPhoenix do
  def encode_to_iodata!(data) do
    Poison.encode_to_iodata!(data, pretty: true)
  end
end

And in config/config.exs, add:

config :phoenix, :format_encoders, json: MyApp.PrettyPoisonEncoderForPhoenix

After restarting the server, all your json calls should automatically print pretty JSON.

If you only want pretty output in dev, you can instead add the above code in config/dev.exs. If you do that, prod will still output non-pretty JSON.


You can also create a simple wrapper that does what Phoenix.Controller.json/2 does (almost; see note below) but also makes the output pretty:

def pretty_json(conn, data) do
  conn
  |> put_resp_header("content-type", "application/json; charset=utf-8")
  |> send_resp(200, Poison.encode!(data, pretty: true))
end

Usage:

def index(conn, _params) do
  pretty_json conn, [%{a: 1, b: 2}, %{c: 3, d: 4}]
end

Output:

➜ curl localhost:4000
[
  {
    "b": 2,
    "a": 1
  },
  {
    "d": 4,
    "c": 3
  }
]

Note: This is not exactly equivalent to Phoenix.Controller.json/2 as that function only adds the content-type if one is not present. You can use the same logic by copying some code from here.

like image 156
Dogbert Avatar answered Sep 21 '22 15:09

Dogbert