Absinthe.Phoenix

Subscriptions

This readme is going to be the primary source of info on how to use Absinthe Subscriptions while they’re in beta.

Libraries you’ll need:

{:absinthe, github: "absinthe-graphql/absinthe"},
{:absinthe_phoenix, github: "absinthe-graphql/absinthe_phoenix"},

In your application supervisor add this line AFTER your existing endpoint supervision line:

supervisor(Absinthe.Subscription, [MyApp.Web.Endpoint]),

Where MyApp.Web.Endpoint is the name of your application’s phoenix endpoint.

In your MyApp.Web.Endpoint module add:

use Absinthe.Phoenix.Endpoint

In your socket add:

Phoenix 1.3

use Absinthe.Phoenix.Socket,
  schema: MyApp.Web.Schema

Phoenix 1.2

  use Absinthe.Phoenix.Socket
  def connect(params, socket) do
    current_user = current_user(params)
    socket = Absinthe.Phoenix.Socket.put_schema(socket, MyApp.Web.Schema)
    {:ok, socket}
  end

Where MyApp.Web.Schema is the name of your Absinthe schema module.

That is all that’s required for setup on the server.

GraphiQL

At this time only the simpler GraphiQL interface supports subscriptions. To use them, just add a :socket option to your graphiql config:

forward "/graphiql", Absinthe.Plug.GraphiQL,
  schema: JLR.Web.Schema,
  socket: JLR.Web.UserSocket,
  interface: :simple

Setting Options

Options like the context can be configured in the def connect callback of your socket

defmodule GitHunt.Web.UserSocket do
  use Phoenix.Socket
  use Absinthe.Phoenix.Socket,
    schema: MyApp.Web.Schema

  transport :websocket, Phoenix.Transports.WebSocket

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

  defp current_user(%{"user_id" => id}) do
    MyApp.Repo.get(User, id)
  end

  def id(_socket), do: nil
end

JavaScript Clients

Name Framework Status
absinthe-phoenix-js (None) Official
apollo-phoenix-websocket Apollo Community (Maintained by @vic)
? Relay (Classic) Missing (Please contribute!)
? Relay (Modern) Missing (Please contribute!)

Schema

Example schema that lets you use subscriptions to get notified when a comment is submitted to a github repo.

See https://hexdocs.pm/absinthe/1.4.0-beta.1/Absinthe.Schema.html#subscription/2 for more details on setting up subscriptions in your schema.

mutation do
  field :submit_comment, :comment do
    arg :repo_full_name, non_null(:string)
    arg :comment_content, non_null(:string)

    resolve &Github.submit_comment/3
  end
end

subscription do
  field :comment_added, :comment do
    arg :repo_full_name, non_null(:string)

    # The topic function is used to determine what topic a given subscription
    # cares about based on its arguments. You can think of it as a way to tell the
    # difference between
    # subscription {
    #   commentAdded(repoFullName: "absinthe-graphql/absinthe") { content }
    # }
    #
    # and
    #
    # subscription {
    #   commentAdded(repoFullName: "elixir-lang/elixir") { content }
    # }
    config fn args, _ ->
      {:ok, topic: args.repo_full_name}
    end

    # this tells Absinthe to run any subscriptions with this field every time
    # the :submit_comment mutation happens.
    # It also has a topic function used to find what subscriptions care about
    # this particular comment
    trigger :submit_comment, topic: fn comment ->
      comment.repository_name
    end

    resolve fn %{comment_added: comment}, _, _ ->
      # this function is often not actually necessary, as the default resolver
      # will pull the root value off properly.
      # It's only here to show what happens.
      {:ok, comment}
    end

  end
end