Authenticated and Unauthenticated "Endpoints" with Elixir and Absinthe

I have a scenario where I want one GraphQL resolver to be reached without first being authenticated (The Sign In Endpoint). But I can’t figure out how to separate the the authenticated and unauthenticated routes.

Here is my router:

ROUTER:

  scope "/graphql/unauthenticated" do
    pipe_through([:api])

    forward "/", Absinthe.Plug, schema: StatcastersWeb.Schema
  end

  scope "/graphql" do
    pipe_through([:api, :authenticated])

    forward "/", Absinthe.Plug, schema: StatcastersWeb.Schema
  end

ERROR:

Absinthe.Plug has already been forwarded to. A module can only be forwarded a single time.

I understand the error, but what do I do here? I want to have a place to tell GraphQL that this query doesn’t need to be authenticated. How can I achieve this?

2 Likes

This is a Phoenix router limitation. Fortunately it’s pretty easy to work around, we can just create an interstitial module that wraps Absinthe.Plug

defmodule My.Absinthe.Plug do
  defdelegate init(opts), to: Absinthe.Plug
  defdelegate call(conn, opts), to: Absinthe.Plug
end

Then you can just do forward "/", My.Absinthe.Plug, schema: ... for one of them and it’ll be fine.

16 Likes

Perfect. Thanks for the help, Ben.

I hit the same problem. Thanks for the workaround. But why Phonix router intro this limitation?

Is this workaround still working? I getting this error

My.Absinthe.Plug has already been forwarded to. A module can only be forwarded a single time.
1 Like

Hi @apellizzn can you show your router code? If I had to guess you’re forwarding to the new plug in both cases when you should be forwarding to the normal plug once, and your new plug once.

1 Like

@apellizzn hi both of you guys, I’m the same to you before, how about now?
With upgrading to the latest Phoenix 1.7.0, I’ve been fixing almost all of routers in my company’s Umbrella project. Could anyone help me, please?