8
votes

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

1

1 Answers

15
votes

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.