apollo-tracing-elixir icon indicating copy to clipboard operation
apollo-tracing-elixir copied to clipboard

Socket example?

Open bjunc opened this issue 7 years ago • 6 comments

Any suggestions on setting up tracing for websocket?

bjunc avatar Mar 30 '18 13:03 bjunc

@bjunc this isn't something that we've figured out quite yet, mainly because existing use cases are push-based, so the resolution has been from a pre-formed data structure. Is your use case around subscriptions as well or are you issuing queries over websockets?

athal7 avatar Apr 02 '18 12:04 athal7

My use-case is essentially a typical request/response of queries/mutations, but over socket. We use it for server-to-server communication, prior to page load. Our Phoenix GraphQL API is completely headless, and hosted on a different box than the presentation layer (built in Nuxt, which is SSR Vue.js). So when someone makes a page request to the Nuxt app, the Nodejs part of the app connects to the Phoenix app via socket, makes a few requests, renders the HTML, sends that to the browser, and then closes the socket connection. Future API calls from the browser are done via HTTP.

So, we're not using GraphQL for subscriptions / push.

bjunc avatar Apr 02 '18 12:04 bjunc

Got it, so in that case I think you should be able to follow the examples in the README for non-plug-based resolution.

athal7 avatar Apr 02 '18 12:04 athal7

Are you referring to the custom_absinthe_runner? I'm not really sure how that'd slot in. The only areas we really tweak to allow GraphQL over socket, is in connect/2. For instance:

def connect(%{"token" => token} = _params, socket) do
  case FooApp.Auth.Guardian.decode_and_verify(token) do
    {:ok, claims} ->
      case FooApp.Auth.Guardian.resource_from_claims(claims) do
        {:ok, user} ->
          # Assign current_user to Absinthe socket context for use in resolve
          socket = Absinthe.Phoenix.Socket.put_opts(socket, context: %{current_user: user})
          {:ok, socket}

        {:error, _reason} ->
          :error
      end

    {:error, _reason} ->
      :error
  end
end

Do you maybe have a more complete example / description of how tracing can fit into a socket request/response? Is it something the Absinthe team would need to build into Absinthe.Phoenix.Socket?

bjunc avatar Apr 02 '18 13:04 bjunc

From what I can tell it looks like you can specify a pipeline when you include the Absinthe Phoenix Socket, e.g.

defmodule MyApp.Web.UserSocket do
  use Phoenix.Socket
  use Absinthe.Phoenix.Socket
    schema: MyApp.Web.Schema,
    pipeline: ApolloTracing.Pipeline

  transport :websocket, Phoenix.Transports.WebSocket

  def connect(params, socket) do
    socket = Absinthe.Phoenix.Socket.put_options(socket, [
      context: %{current_user: find_current_user(params)}
    ])
    {:ok, socket}
  end

  def id(_socket), do: nil
end

This doesn't seem to be documented well either on their side or on our side. Let me know if this works for you, and if so, we can add some documentation here.

athal7 avatar Apr 02 '18 16:04 athal7

Thanks @athal7, I'll take a look and report back.

bjunc avatar Apr 04 '18 21:04 bjunc