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 web_socket() :: GenServer.server()
Link to this section Functions
@spec await_reply!(Req.Response.t() | reference(), non_neg_integer()) :: AbsintheClient.WebSocket.Reply.t()
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"}}
@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"}}
@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
@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
@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 toconnect/2
the request'sbase_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 toMint.HTTP.connect/4
for the initial HTTP request::timeout
- socket connect timeout in milliseconds, defaults to30_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 isnil
.:parent
- pid of the process starting the connection. The socket monitors this process and shuts down when the parent process exits. Defaults toself()
.
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
@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
@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"}}
@spec run(Req.Request.t()) :: {Req.Request.t(), Req.Response.t() | Exception.t()}
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"}}