Вы можете использовать штекер phoenix accepts
и комбинацию двух разных видов / макетов
# 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 уже позаботилсяof на page.html.eex
в макетах, поэтому добавьте следующее к вашему page_view.ex
defmodule TestExWeb.PageView do
use TestExWeb, :view
def render("index.json", %{data: data}) do
%{
data: data
}
end
end
Два недостатка с этим решением:
- Этот фрагмент кода необходим в каждом контроллере (Может быть, вы можете обойти это с помощью плагина после того, как «отправили» ответ)
- Вы используете внутреннюю переменную phoenix