0

Plugs 管道是构建应用程序的绝佳方式。目前虽然我只在请求到达控制器之前应用管道来过滤/格式化数据。有没有办法在处理每个视图后应用管道运行?我有一个 JSON api,我在每个视图渲染函数上运行两个数据转换。

  def render("app.json", %{app: app}) do
    app
    ...
    |> ApiHelpers.add_data_property
    |> ProperCase.to_camel_case
  end 

有没有更简洁的方法来处理这个问题,或者这是我只需要在我的视图模块中的每个渲染函数上做的事情?

更新

正如@sabiwara 指出的那样,有register_before_send回调。我已经尝试为我的用例实现它,但似乎回调更多的是用于记录而不是操纵响应。

我试过了

  def call(conn, _opts) do
    register_before_send(conn, fn conn ->
      resp(conn, conn.status, conn.resp_body |> FormatHelpers.camelize() |> ApiHelpers.add_data_property())
    end)
  end

conn.resp_body是我尝试将其转换为地图但仍然不行的列表。

4

1 回答 1

0

在 JSON 内容被编码之前对其进行转换的一种方法是在配置中定义一个自定义编码器:https ://hexdocs.pm/phoenix/Phoenix.Template.html#module-format-encoders

添加一个新文件:

defmodule MyJSONEncoder do
  def encode_to_iodata!(data) do
    data
    |> transform_data()
    |> Jason.encode_to_iodata!()
  end
  
  def transform_data(data) do
    # whatever transformation you need to make
    %{data: data}
  end
end

config.exs

config :phoenix, :format_encoders, json: MyJSONEncoder

不是 100% 肯定这是最好的方法,它会触及每一个响应,但它似乎适合您的用例。

于 2020-09-21T05:26:32.960 回答