elixir - mac - Phoenix-controlador con render múltiple
phoenix framework tutorial (2)
Como dijo Gazler, probablemente lo mejor es tener tuberías separadas, pero algo como esto se puede hacer de manera agradable con la coincidencia de patrones en las mismas acciones del controlador:
def show(conn, %{"format" => "html"} = params) do
# ...
end
def show(conn, %{"format" => "json"} = params) do
# ...
end
O si los cuerpos de la función son los mismos, y solo desea renderizar una plantilla basada en los encabezados de aceptación, puede hacer:
def show(conn, params) do
# ...
render conn, :show
end
Al pasar un átomo como nombre de la plantilla, phoenix comprobará los encabezados de aceptación y renderizará la plantilla .json
o .html
.
Intentando crear una aplicación con Elixir + Phoenix, que podría manejar las solicitudes de "navegador" y "api" para manejar sus recursos.
¿Es posible hacerlo sin tener que hacer algo así?
scope "/", App do
pipe_through :browser
resources "/users", UserController
end
scope "/api", App.API as: :api do
pipe_through :api
resources "/users", UserController
end
lo que significaría tener que crear dos controladores, que podrían tener el mismo comportamiento, excepto que representará HTML con la canalización del navegador y, digamos JSON, para la tubería de la API .
Estaba pensando que tal vez algo así como los Rails respond_to do |format| ...
respond_to do |format| ...
No lo recomendaría (recomendaría tener dos controladores y mover su lógica a un módulo diferente al que llaman ambos controladores) pero se puede hacer. Puede compartir un controlador, pero aún necesita una tubería por separado para garantizar que se establezca el tipo de respuesta correcta (html / json).
Lo siguiente usará el mismo controlador y vista, pero procesará json o html dependiendo de la ruta. "/" es html, "/ api" es json.
Enrutador
defmodule ScopeExample.Router do
use ScopeExample.Web, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", ScopeExample do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
end
scope "/api", ScopeExample do
pipe_through :api # Use the default browser stack
get "/", PageController, :index
end
end
Controlador:
defmodule ScopeExample.PageController do
use ScopeExample.Web, :controller
plug :action
def index(conn, params) do
render conn, :index
end
end
Ver:
defmodule ScopeExample.PageView do
use ScopeExample.Web, :view
def render("index.json", _opts) do
%{foo: "bar"}
end
end
También puede compartir el enrutador y tener todo servido por la misma ruta si usa un enrutador como:
defmodule ScopeExample.Router do
use ScopeExample.Web, :router
pipeline :browser do
plug :accepts, ["html", "json"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
end
scope "/", ScopeExample do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
end
end
Luego puede especificar el formato usando ?format=json
al final de la url. Sin embargo, recomendaría ir con diferentes urls para su API y sitio.