absinthe_graphql_ws icon indicating copy to clipboard operation
absinthe_graphql_ws copied to clipboard

GraphiQL subscription

Open acrogenesis opened this issue 3 years ago • 6 comments

I'm looking into the docs but I couldn't find if there's a way to use the absinthe provided graphiql interface with graphql-ws

acrogenesis avatar Jan 11 '22 01:01 acrogenesis

Hi @acrogenesis. We have not tried to get graphiql working with graphql-ws.

My understanding is that absinthe ships with its own modified graphiql, with the frontend modified in such a way that it requires using Absinthe.Phoenix.Channel.

In the application we started this library to support, we run two sockets. One of them is only to support graphiql:

socket "/api/absinthe", Web.AbsintheSocket,
    websocket: true,
    longpoll: false,
    check_origin: false

socket "/api/graphql-ws", Web.GraphqlWSSocket,
    websocket: [
        path: "",
        subprotocols: ["graphql-transport-ws"]
    ]

The Web.AbsintheSocket is straight out of the absinthe docs:

defmodule Web.AbsintheSocket do
  use Phoenix.Socket

  ## Channels

  channel(
    "__absinthe__:*",
    Web.GraphqlChannel,
    assigns: %{
      __absinthe_schema__: Web.Api.Schema
    }
  )

  @impl true
  def connect(_params, socket, _connect_info) do
    {:ok, socket}
  end

  @impl true
  def id(_socket), do: nil
end
defmodule Web.GraphqlChannel do
  use Phoenix.Channel
  alias Absinthe.Phoenix.Channel, as: AbsintheChannel

  def join(topic, payload, socket), do: AbsintheChannel.join(topic, payload, socket)
  def handle_in(message, payload, socket), do: AbsintheChannel.handle_in(message, payload, socket)
end

This just means that we need to make sure that graphiql hits /api/absinthe/websocket for its subscriptions.

Work that we have scheduled for the next few weeks is going to involve adding graphql subscriptions to a new application—I thought that for expediency we would use this same approach in the near term, but your issue has me thinking that maybe it would be better to solve this problem, so that we don't have to duplicated authentication logic between two sockets.

Let me know if this will work for you, or if you have any ideas about a better long term solution... This might also be a good topic of discussion for the #absinthe-graphql channel in the Elixir slack... I wonder if this is something that absinthe itself could support.

sax avatar Jan 11 '22 01:01 sax

I think we could create a Plug with a modified graphiql that uses graphql-ws. Almost a copy paste of absinthe graphiql plug but modifying https://github.com/absinthe-graphql/absinthe_plug/blob/60c05541a015cb53b618fcbf9a277767e149ea73/lib/absinthe/plug/graphiql/graphiql_workspace.html.eex#L41

acrogenesis avatar Jan 11 '22 15:01 acrogenesis

One of my colleagues suggested that it would be nice to be able to modify graphiql with application-specific changes. That makes me wonder if it would be better ship a generator library, rather than a plug itself... Though looking at the plug in absinthe, it seems like quite a bit of code to generate.

I wonder if absinthe could be extended to support pulling in application-specific templates in its plug. That would make it easier to solve this with documentation in this library.

sax avatar Jan 11 '22 16:01 sax

I recall there were plans to extract graphiql out of absinthe_plug. That could be used to bump the graphiql version as quite a few versions have been released since the one that is bundled with absinthe_plug. Making the graphql websocket protocol pluggable would also be awesome.

ping @benwilson512

maartenvanvliet avatar Jan 11 '22 17:01 maartenvanvliet

That does seem as a better more scalable solution. Perhaps something similar to Apollo Server LandingPlugins https://www.apollographql.com/docs/apollo-server/api/plugin/landing-pages/

acrogenesis avatar Jan 11 '22 20:01 acrogenesis

@maartenvanvliet @benwilson512 I don't see an issue in GitHub to track the graphiql extraction. Is that something that would be helpful in file in the absinthe repo and link to here?

sax avatar Jan 26 '22 19:01 sax