View Source AbsintheClient.WebSocket (absinthe_client v0.1.1)

Req adapter for Absinthe subscriptions.

The WebSocket does the following:

  • Pushes documents to the GraphQL server and forwards replies to the callers.

  • Manages any subscriptions received, including automatically re-subscribing in the event of a connection loss.

Under the hood, WebSocket connections are Slipstream socket processes which are usually managed by an internal AbsintheClient supervisor.

examples

Examples

Performing a query operation over a WebSocket:

iex> req = Req.new(base_url: "http://localhost:4002") |> AbsintheClient.attach()
iex> ws = req |> AbsintheClient.WebSocket.connect!()
iex> Req.request!(req, web_socket: ws, graphql: ~S|{ __type(name: "Repo") { name } }|).body["data"]
%{"__type" => %{"name" => "Repo"}}

Performing an async query operation and awaiting the reply:

iex> req = Req.new(base_url: "http://localhost:4002") |> AbsintheClient.attach()
iex> ws = req |> AbsintheClient.WebSocket.connect!()
iex> reply =
...>   req
...>   |> Req.request!(web_socket: ws, async: true, graphql: ~S|{ __type(name: "Repo") { name } }|)
...>   |> AbsintheClient.WebSocket.await_reply!()
iex> reply.payload["data"]
%{"__type" => %{"name" => "Repo"}}

handling-messages

Handling messages

Results will be sent to the caller as WebSocket.Message structs.

In a GenServer for instance, you would implement a handle_info/2 callback:

def handle_info(%AbsintheClient.WebSocket.Message{payload: payload}, state) do
  # code...
  {:noreply, state}
end

Link to this section Summary

Functions

Awaits the server's response to a pushed document or raises an error.

Awaits the server's response to a pushed document.

Same as connect/1 but raises on error.

Same as connect/2 but raises on error.

Dynamically starts (or re-uses already started) AbsintheWs process with the given options

Connects to an Absinthe WebSocket.

Pushes a query to the server via the given socket.

Performs a GraphQL operation.

Link to this section Types

@type graphql() :: String.t() | {String.t(), nil | map()}
@type web_socket() :: GenServer.server()

Link to this section Functions

Link to this function

await_reply!(response_or_ref, timeout \\ 5000)

View Source

Awaits the server's response to a pushed document or raises an error.

examples

Examples

iex> req = Req.new(base_url: "http://localhost:4002") |> AbsintheClient.attach(async: true)
iex> ws = req |> AbsintheClient.WebSocket.connect!()
iex> res = Req.post!(req, web_socket: ws, graphql: ~S|{ __type(name: "Repo") { name } }|)
iex> AbsintheClient.WebSocket.await_reply!(res).payload["data"]
%{"__type" => %{"name" => "Repo"}}
Link to this function

await_reply(response_or_ref, timeout \\ 5000)

View Source
@spec await_reply(Req.Response.t() | reference(), non_neg_integer()) ::
  {:ok, AbsintheClient.WebSocket.Reply.t()} | {:error, :timeout}

Awaits the server's response to a pushed document.

examples

Examples

iex> req = Req.new(base_url: "http://localhost:4002") |> AbsintheClient.attach(async: true)
iex> {:ok, ws} = AbsintheClient.WebSocket.connect(req)
iex> {:ok, res} = Req.request(req, web_socket: ws, graphql: ~S|{ __type(name: "Repo") { name } }|)
iex> {:ok, reply} = AbsintheClient.WebSocket.await_reply(res)
iex> reply.payload["data"]
%{"__type" => %{"name" => "Repo"}}
Link to this function

connect!(request_or_options)

View Source
@spec connect!(request_or_options :: Req.Request.t() | keyword()) :: web_socket()

Same as connect/1 but raises on error.

examples

Examples

From a request:

iex> ws = Req.new(base_url: "http://localhost:4002") |> AbsintheClient.WebSocket.connect!()
iex> ws |> GenServer.whereis() |> Process.alive?()
true

From keyword options:

iex> ws = AbsintheClient.WebSocket.connect!(url: "ws://localhost:4002/socket/websocket")
iex> ws |> GenServer.whereis() |> Process.alive?()
true
Link to this function

connect!(request, options)

View Source
@spec connect!(
  Req.Request.t(),
  keyword()
) :: web_socket()

Same as connect/2 but raises on error.

examples

Examples

iex> ws =
...>  Req.new(base_url: "http://localhost:4002")
...>  |> AbsintheClient.WebSocket.connect!(url: "/socket/websocket")
iex> ws |> GenServer.whereis() |> Process.alive?()
true
Link to this function

connect(request_or_options)

View Source
@spec connect(request_or_options :: Req.Request.t() | keyword()) ::
  {:ok, web_socket()} | {:error, Exception.t()}

Dynamically starts (or re-uses already started) AbsintheWs process with the given options:

  • :url - URL where to make the WebSocket connection. When provided as an option to connect/2 the request's base_url will be prepended to this path. The default value is "/socket/websocket".

  • :headers - list of headers to send on the initial HTTP request. Defaults to [].

  • :connect_options - list of options given to Mint.HTTP.connect/4 for the initial HTTP request:

    • :timeout - socket connect timeout in milliseconds, defaults to 30_000.
  • :connect_params - Optional. Custom params to be sent when the WebSocket connects. Defaults to sending the bearer Authorization token if one is present on the request. The default value is nil.

  • :parent - pid of the process starting the connection. The socket monitors this process and shuts down when the parent process exits. Defaults to self().

Note that when connect/2 returns successfully, it indicates that the WebSocket process has started. The process must then connect to the GraphQL server and join the relevant topic(s) before it can send and receive messages.

examples

Examples

From a request:

iex> req = Req.new(base_url: "http://localhost:4002") |> AbsintheClient.attach()
iex> {:ok, ws} = req |> AbsintheClient.WebSocket.connect()
iex> ws |> GenServer.whereis() |> Process.alive?()
true

From keyword options:

iex> {:ok, ws} = AbsintheClient.WebSocket.connect(url: "ws://localhost:4002/socket/websocket")
iex> ws |> GenServer.whereis() |> Process.alive?()
true
Link to this function

connect(request, options)

View Source
@spec connect(
  Req.Request.t(),
  keyword()
) :: {:ok, web_socket()} | {:error, Exception.t()}

Connects to an Absinthe WebSocket.

Refer to connect/1 for more information.

examples

Examples

With the default URL path:

iex> req = Req.new(base_url: "http://localhost:4002") |> AbsintheClient.attach()
iex> {:ok, ws} = req |> AbsintheClient.WebSocket.connect()
iex> ws |> GenServer.whereis() |> Process.alive?()
true

With a custom URL path:

iex> req = Req.new(base_url: "http://localhost:4002") |> AbsintheClient.attach()
iex> {:ok, ws} = req |> AbsintheClient.WebSocket.connect(url: "/socket/websocket")
iex> ws |> GenServer.whereis() |> Process.alive?()
true
Link to this function

push(request_or_socket, graphql)

View Source
@spec push(request_or_socket :: Req.Request.t() | web_socket(), graphql()) ::
  reference()

Pushes a query to the server via the given socket.

examples

Examples

iex> {:ok, req} = AbsintheClient.WebSocket.connect(url: "ws://localhost:4002/socket/websocket")
iex> ref = AbsintheClient.WebSocket.push(req, ~S|{ __type(name: "Repo") { name } }|)
iex> AbsintheClient.WebSocket.await_reply!(ref).payload["data"]
%{"__type" => %{"name" => "Repo"}}

Performs a GraphQL operation.

examples

Examples

iex> req = Req.new(base_url: "http://localhost:4002") |> AbsintheClient.attach()
iex> ws = req |> AbsintheClient.WebSocket.connect!()
iex> Req.request!(req, web_socket: ws, graphql: ~S|{ __type(name: "Repo") { name } }|).body["data"]
%{"__type" => %{"name" => "Repo"}}