davidarmstronglewis
Duplicate scope entries with different pipe_through?
Hey all! Just ran into a small considering that I don’t have a good answer for.
I’m building an application that uses Absinthe and I’d like to expose its GraphiQL interface. One fun aspect of this is that any external traffic to this application’s admin/ routes is denied by default unless you’re on VPN. Because of this I want to expose both the Phoenix dashboard under the /admin scope with…
scope "/admin" do
import Phoenix.LiveDashboard.Router
pipe_through [:fetch_session, :protect_from_forgery]
live_dashboard "/dashboard", metrics: MyApplicationWeb.Telemetry
end
scope "/admin" do
pipe_through [:api]
forward "/graphiql", Absinthe.Plug.GraphiQL,
schema: MyApplicationWeb.Schema,
interface: :playground,
context: %{pubsub: MyApplicationWeb.Endpoint}
end
An issue I’m seeing with this is that I’m duplicating scopes here and don’t understand enough about the Phoenix Router to know if this the right way to expose two different endpoints that require different pipelines under the same /admin scope. I’ve gone ahead and tested out keeping them under the same scope but ran into some funky behavior where depending on how I order things I’ll get broken behavior.
For example, this seems to work:
scope "/admin" do
pipe_through [:api]
forward "/graphiql", Absinthe.Plug.GraphiQL,
schema: MyApplicationWeb.Schema,
interface: :playground,
context: %{pubsub: MyApplicationWeb.Endpoint}
import Phoenix.LiveDashboard.Router
pipe_through [:fetch_session, :protect_from_forgery]
live_dashboard "/dashboard", metrics: MyApplicationWeb.Telemetry
end
Whereas this does not work:
scope "/admin" do
import Phoenix.LiveDashboard.Router
pipe_through [:fetch_session, :protect_from_forgery]
live_dashboard "/dashboard", metrics: MyApplicationWeb.Telemetry
pipe_through [:api]
forward "/graphiql", Absinthe.Plug.GraphiQL,
schema: MyApplicationWeb.Schema,
interface: :playground,
context: %{pubsub: MyApplicationWeb.Endpoint}
end
Without knowing much more about how this works “under the hood”, I’m really just guessing at which will cause fewer problems in the long run. Curious if people have dealt with this situation before and how you think about ![]()
Most Liked
al2o3cr
scope is fine to repeat - all it does is push a set of options onto the router’s stack:
The ordering issue you’re seeing is because pipe_through adds the pipes to the scope, but they only apply to calls to route and scope following them in the scope. For instance, here’s where Scope.push grabs the current value of pipes:
As a result, the GraphiQL forward will see just the api pipe in the first ordering, and fetch_session, protect_from_forgery, api in the second.
IMO the clearest way to avoid needing to remember exactly how this ordering thing works is:
- keep
pipe_throughcalls together at the top of a scope - different pipelines? different scope.







