Elixir 在处理请求后运行塞管道

Elixir 在处理请求后运行塞管道,elixir,phoenix-framework,plug,Elixir,Phoenix Framework,Plug,插头管道是构建应用程序的一种神奇方式。目前,我只在请求到达控制器之前应用管道来过滤/格式化数据。是否有一种方法可以在处理每个视图后应用管道来运行?我有一个JSON api,在每个视图渲染函数上运行两个数据转换 def render("app.json", %{app: app}) do app ... |> ApiHelpers.add_data_property |> ProperCase.to_camel_case en

插头管道是构建应用程序的一种神奇方式。目前,我只在请求到达控制器之前应用管道来过滤/格式化数据。是否有一种方法可以在处理每个视图后应用管道来运行?我有一个JSON api,在每个视图渲染函数上运行两个数据转换

  def render("app.json", %{app: app}) do
    app
    ...
    |> ApiHelpers.add_data_property
    |> ProperCase.to_camel_case
  end 
是否有更干净的方法来处理此问题,或者这是我只需要在视图模块中的每个渲染函数上执行的操作

更新

正如@sabiwara所指出的,在发送之前有一个
register\u
回调。我已经尝试在我的用例中实现它,但回调似乎更多的是用于日志记录,而不是操纵响应

我试过了

  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
是一个列表,我已经尝试将其转换为映射,但仍然不好。

在编码JSON内容之前转换JSON内容的一种方法是在配置中定义自定义编码器:

添加新文件:

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%确定这是最好的方法,而且它会触及每个响应,但它似乎对您的用例很有效。

您在发送之前是否尝试过注册?我之前没有说过,但既然你提到了,我就试一试。看来回调更多的是用于日志记录,而不是操纵响应体。我更新了我的问题,以显示我的尝试。谢谢确实,它无法工作,因为注册的回调将在发送之前调用,但在编码JSON正文之后调用。谢谢你的努力!