graphql-elixir / plug_graphql

Plug (Phoenix) integration for GraphQL Elixir
Other
126 stars 7 forks source link

Workaround double `forward` error #7

Open joshprice opened 8 years ago

joshprice commented 8 years ago

Phoenix errors when a second forward is declared to the same Plug. This can be worked around by wrapping the GraphQL.Plug.Endpoint with configuration in a new module Plug.

forward "/hello", GraphQL.Plug.Endpoint, schema: {GraphQL.Schema.HelloWorld, :schema}
forward "/blog",  GraphQL.Plug.Endpoint, schema: {GraphQL.Schema.SimpleBlog, :schema}

Gives this error:

== Compilation error on file web/router.ex ==
** (ArgumentError) `GraphQL.Plug.Endpoint` has already been forwarded to. A module can only be forwarded a single time.
    (phoenix) lib/phoenix/router/route.ex:171: Phoenix.Router.Route.forward_path_segments/3
    web/router.ex:29: (module)
    (stdlib) erl_eval.erl:669: :erl_eval.do_apply/6
    (elixir) lib/kernel/parallel_compiler.ex:100: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/8

Arguably this may be a bug in Phoenix, as this seems like a reasonable thing to do...

There are 2 workarounds:

  1. The plug wrapper workaround (suggested by @chrismccord) which hides the identity of the underlying plug

    # Hello World wrapper
    defmodule HelloWorld do
     plug GraphQL.Plug.Endpoint, schema: {GraphQL.Schema.HelloWorld, :schema}
    end
    
    # Simple Blog wrapper
    defmodule SimpleBlog do
     plug GraphQL.Plug.Endpoint, schema: {GraphQL.Schema.SimpleBlog, :schema}
    end
    
    forward "/hello", HelloWorld
    forward "/blog",  SimpleBlog
  2. This is the get/post workaround which avoids forward altogether, losing ability to handle other HTTP verbs.

    # Hello World example
    get  "/hello", GraphQL.Plug.Endpoint, schema: {GraphQL.Schema.HelloWorld, :schema}
    post "/hello", GraphQL.Plug.Endpoint, schema: {GraphQL.Schema.HelloWorld, :schema}
    
    # Simple Blog example
    get  "/blog",  GraphQL.Plug.Endpoint, schema: {GraphQL.Schema.SimpleBlog, :schema}
    post "/blog",  GraphQL.Plug.Endpoint, schema: {GraphQL.Schema.SimpleBlog, :schema}

The error is fired here and perhaps could account for differing configuration? https://github.com/phoenixframework/phoenix/blob/master/lib/phoenix/router/route.ex#L170-L172

tillsc commented 3 months ago

Thanks for your writeup! In my case I also needed to include use Plug.Builder in my dummy modules