raarts
raarts

Reputation: 2961

behavior of nested scope definitions in web/router.ex

The docs do not mention this at all. Is it allowed to nest scope definitions, and if so what is the defined behaviour for the following in web/router.ex:

scope "/:locale", MyApp do
  pipe_through [:browser, :locale]

  scope "/auth", MyApp do
    pipe_through [:auth]

    get "/", PageController, :dummy
  end

  get "/", PageController, :dummy
end

Do pipes chain, .i.e are the /:locale/auth requests route through :browser, :locale AND :auth? Any gotchas?

Upvotes: 7

Views: 2202

Answers (2)

Justin Wood
Justin Wood

Reputation: 10061

You will have the following routes

# The following route has the :browser and :locale plugs
/:locale/      # Points to MyApp.PageController.dummy

# The following route has the :browser, :locale and :auth plugs
/:locale/auth/ # Points to MyApp.MyApp.PageController.dummy

I feel like you do not want to actually point to MyApp.MyApp.PageController, so you can define a scope/2 without specifying the alias.

scope "/:locale", MyApp do
  pipe_through [:browser, :locale]

  scope "/auth" do
    pipe_through [:auth]

    get "/", PageController, :dummy
  end
end

This will now just point your auth route to MyApp.PageController.

Upvotes: 4

Dogbert
Dogbert

Reputation: 222148

Yes, it is allowed to scope definitions, and pipelines are inherited by nested scopes. The Phoenix repo contains tests for pipelines in nested scopes which assert that all the pipe_through in the parent scopes are inherited by the routes in the child scopes.

scope "/browser" do
  pipe_through :browser
  get "/root", SampleController, :index

  scope "/api" do
    pipe_through :api
    get "/root", SampleController, :index
  end
end

# ...

test "invokes pipelines in a nested scope" do
  conn = call(Router, :get, "/browser/api/root")
  assert conn.private[:phoenix_pipelines] == [:browser, :api]
  assert conn.assigns[:stack] == "api"
end

Upvotes: 5

Related Questions