Phoenix :具有相同资源的 JSON 和 HTML 表示
Phoenix : Having a JSON and HTML representation of the same resource
我开始在教程之外为一个小用例使用 Phoenix。到目前为止还不错,但我对以下内容有点吃惊。
我有一个资源 "recording",我想在 JSON 中的 /api/recordings 和 /recording 使用模板访问,结果是 HTML。
理想情况下,Ecto 表示是唯一的,甚至控制器的一部分也将被共享?
现在我必须有 2 个资源 recordingAPI 和 recordingHTML,或者 2 个控制器和 1 个资源。
有什么例子吗?我一直在寻找一个或另一个,但没有找到用于同一资源的 :api 管道和 :browser 管道。
谢谢
您可以利用 phoenix accepts
插件和两个不同 views/layouts
的组合
# router.ex
defmodule TestExWeb.Router do
use TestExWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", TestExWeb do
pipe_through :browser
get "/recording", PageController, :index
end
scope "/api", TestExWeb do
pipe_through :api
get "/recording", PageController, :index
end
end
如您所见,:browser
使用 :accepts ["html"]
而 :api
使用 :accepts ["json"]
。您可以在 conn
的私有结构中找到它,并像这样在控制器中使用它:
defmodule TestExWeb.PageController do
use TestExWeb, :controller
def index(%{private: %{phoenix_format: format}} = conn, _params) do
data = "Hello World"
render(conn, "index.#{format}", data: data)
end
end
现在,您只需要告诉 phoenix 如何渲染您的 json,html 已经在布局中由 page.html.eex
处理,因此将以下内容添加到您的 page_view.ex
defmodule TestExWeb.PageView do
use TestExWeb, :view
def render("index.json", %{data: data}) do
%{
data: data
}
end
end
此解决方案的两个缺点:
- 您需要在每个控制器中使用此格式片段(也许您可以在 "sent" 响应后使用插件来规避此问题)
- 您正在使用 phoenix 的内部变量
我开始在教程之外为一个小用例使用 Phoenix。到目前为止还不错,但我对以下内容有点吃惊。
我有一个资源 "recording",我想在 JSON 中的 /api/recordings 和 /recording 使用模板访问,结果是 HTML。
理想情况下,Ecto 表示是唯一的,甚至控制器的一部分也将被共享?
现在我必须有 2 个资源 recordingAPI 和 recordingHTML,或者 2 个控制器和 1 个资源。
有什么例子吗?我一直在寻找一个或另一个,但没有找到用于同一资源的 :api 管道和 :browser 管道。
谢谢
您可以利用 phoenix accepts
插件和两个不同 views/layouts
# router.ex
defmodule TestExWeb.Router do
use TestExWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", TestExWeb do
pipe_through :browser
get "/recording", PageController, :index
end
scope "/api", TestExWeb do
pipe_through :api
get "/recording", PageController, :index
end
end
如您所见,:browser
使用 :accepts ["html"]
而 :api
使用 :accepts ["json"]
。您可以在 conn
的私有结构中找到它,并像这样在控制器中使用它:
defmodule TestExWeb.PageController do
use TestExWeb, :controller
def index(%{private: %{phoenix_format: format}} = conn, _params) do
data = "Hello World"
render(conn, "index.#{format}", data: data)
end
end
现在,您只需要告诉 phoenix 如何渲染您的 json,html 已经在布局中由 page.html.eex
处理,因此将以下内容添加到您的 page_view.ex
defmodule TestExWeb.PageView do
use TestExWeb, :view
def render("index.json", %{data: data}) do
%{
data: data
}
end
end
此解决方案的两个缺点:
- 您需要在每个控制器中使用此格式片段(也许您可以在 "sent" 响应后使用插件来规避此问题)
- 您正在使用 phoenix 的内部变量