30

リソースを処理するために「ブラウザ」と「API」の両方のリクエストを処理できる Elixir + Phoenix を使用してアプリを作成しようとしています。

そのようなことをしなくてもそれを行うことは可能ですか:

scope "/", App do
  pipe_through :browser

  resources "/users", UserController
end

scope "/api", App.API as: :api do
  pipe_through :api

  resources "/users", UserController
end

これは、ブラウザパイプラインで HTML をレンダリングし、 APIパイプラインで JSONをレンダリングすることを除いて、同じ動作をする可能性のある 2 つのコントローラーを作成する必要があることを意味します。

おそらくRailsのようなものだと思っていましたrespond_to do |format| ...

4

2 に答える 2

23

私はそれをお勧めしません (2 つのコントローラーを用意し、両方のコントローラーによって呼び出される別のモジュールにロジックを移動することをお勧めします) が、それは可能です。コントローラーを共有できますが、正しい応答タイプ (html/json) が設定されていることを確認するには、別のパイプラインが必要です。

以下は同じコントローラーとビューを使用しますが、ルートに応じて json または html をレンダリングします。「/」はhtml、「/api」はjsonです。

ルーター:

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

コントローラ:

defmodule ScopeExample.PageController do
  use ScopeExample.Web, :controller

  plug :action

  def index(conn, params) do
    render conn, :index
  end
end

意見:

defmodule ScopeExample.PageView do
  use ScopeExample.Web, :view

  def render("index.json", _opts) do
    %{foo: "bar"}
  end
end

次のようなルーターを使用する場合、ルーターを共有して、すべてを同じルートで処理することもできます。

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

その後、URL の最後に使用して形式を指定できます?format=json。ただし、API とサイトには別の URL を使用することをお勧めします。

于 2015-06-03T15:40:46.060 に答える