问题描述
插件管道是一种构建应用程序的绝妙方法。目前,尽管我只是在请求到达控制器之前才应用管道对数据进行过滤/格式化。是否有一种方法可以应用管道以在处理每个视图之后运行?我有一个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
是我尝试将其转换为地图的列表,但仍然没有效果。
解决方法
一种在编码之前转换JSON内容的方法是在配置中定义一个自定义编码器:https://hexdocs.pm/phoenix/Phoenix.Template.html#module-format-encoders
添加新文件:
<img src="http://127.0.0.1:8000/product_image">
并转到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
不能100%地确定这是最好的方法,它会触及每个响应,但是对于您的用例来说似乎效果很好。