This document provides all of the API documentation for reason-urql
.
reason-urql
comes with a set of custom hooks to use in your ReasonReact components, including useQuery
, useMutation
, useDynamicMutation
, and useSubscription
. These are fully type safe and will automatically infer the type of your GraphQL response if using graphql_ppx_re
or graphql_ppx
.
Often, you'll want to fully open
the Hooks
module when using any of the custom hooks – this brings in some necessary types that will assist with pattern matching and type inference around the responses from your GraphQL API.
useQuery
allows you to execute a GraphQL query.
Argument | Type | Description |
---|---|---|
request |
UrqlTypes.request |
The graphql_ppx request representing your query. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
requestPolicy |
option(UrqlTypes.requestPolicy) |
Optional. The request policy to use to execute the query. Defaults to "cache-first" . |
pause |
option(bool) |
Optional. A boolean flag instructing useQuery to pause execution of the subsequent query operation. |
context |
Client.ClientTypes.partialOperationContext |
Optional. A partial operation context object for modifying the execution parameters of this particular query (i.e. using different fetchOptions or a different url ). |
pollInterval |
option(int) |
Optional. Instructs the hook to reexecute the query every pollInterval milliseconds. |
useQuery
returns a tuple containing the result of executing your GraphQL query as a record, response
, and a function for re-executing the query imperatively, executeQuery
.
Return Value | Type | Description |
---|---|---|
result |
UrqlTypes.hookResponse('response) |
A record containing fields for fetching , data , error , and response . response is a variant containing constructors for Data , Error , Fetching and NotFound . Useful for pattern matching to render conditional UI. |
executeQuery |
(~context: UrqlClient.ClientTypes.partialOperationContext=?, unit) => unit |
A function for imperatively re-executing the query. Accepts a single optional labeled argument, context , for altering the query execution. |
open ReasonUrql;
open Hooks;
module GetPokémon = [%graphql
{|
query pokémon($name: String!) {
pokemon(name: $name) {
name
classification
image
}
}
|}
];
[@react.component]
let make = () => {
let request = GetPokémon.make(~name="Cubone", ());
let ({response}, executeQuery) = useQuery(~request, ());
switch (response) {
| Fetching => <div> "Loading"->React.string </div>
| Data(d) =>
<div>
<img src=d##pokemon##image>
<span> d##pokemon##name </span>
<span> d##pokemon##classification </span>
<button
onClick={_event =>
executeQuery(
~context=Client.ClientTypes.partialOperationContext(
~partialOpRequestPolicy=`CacheOnly,
()
)
) |> ignore}
>
{js|Refetch data for $d##pokemon##name|js} -> React.string
</button>
</div>
| Error(_e) => <div> "Error"->React.string </div>
| NotFound => <div> "NotFound"->React.string </div>
}
}
Check out examples/2-query
to see an example of using the useQuery
hook.
useMutation
allows you to execute a GraphQL mutation via the returned executeMutation
function.
Argument | Type | Description |
---|---|---|
request |
UrqlTypes.request |
The graphql_ppx request representing your mutation. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
useMutation
returns a tuple containing the result of executing your GraphQL mutation as a record, result
, and a function for executing the mutation imperatively, executeMutation
. By default, useMutation
does not execute your mutation when your component renders – rather, it is up to you to call executeMutation
when you want to by attaching it to on an event handler or running it inside of an effect.
Return Value | Type | Description |
---|---|---|
result |
UrqlTypes.hookResponse('response) |
A record containing fields for fetching , data , error , and response . response is a variant containing constructors for Data , Error , Fetching and NotFound . Useful for pattern matching to render conditional UI. |
executeMutation |
(~context: Client.ClientTypes.partialOperationContext=?, unit) => Js.Promise.t(Client.ClientTypes.operationResult) |
A function for imperatively executing the mutation. Accepts a single labeled argument, context , for altering the mutation execution. |
open ReasonUrql;
open Hooks;
module LikeDog = [%graphql
{|
mutation likeDog($key: ID!) {
likeDog(key: $key) {
likes
}
}
|}
];
[@react.component]
let make = (~id) => {
let request = LikeDog.make(~key=id, ());
let (_, executeMutation) = useMutation(~request);
<button onClick={_e => executeMutation() |> ignore}>
"Like This Dog!"->React.string
</button>
}
Check out examples/3-mutation
to see an example of using the useMutation
hook.
useDynamicMutation
is quite similar to useMutation
, except it is a hook reserved for when you want to dynamically pass in variables to the executeMutation
function at execution time. In constrast, useMutation
applies variables immediately when it is called at render time.
A good example of a case where useDynamicMutation
comes in handy is when you need to execute a mutation with variables retrieved from useQuery
in the same component. With useMutation
, you'd have to provide a "fallback" variables
argument, then rely on useQuery
running to populate the proper variables
in useMutation
. With useDynamicMutation
, this becomes much simpler – see the Example section below.
Argument | Type | Description |
---|---|---|
definition |
(Js.Json.t => 'response, string, UrqlTypes.graphqlDefinition) |
The definition of your Graphql mutation. If using graphql_ppx_re , this is MyMutation.definition . |
useDynamicMutation
returns nearly the same tuple as useMutation
, containing the result of executing your GraphQL mutation as a record, result
, and a function for executing the mutation imperatively, executeMutation
. Unlike useMutation
, the executeMutation
function returned by useDynamicMutation
accepts all your variables as named arguments.
Return Value | Type | Description |
---|---|---|
result |
UrqlTypes.hookResponse('response) |
A record containing fields for fetching , data , error , and response . response is a variant containing constructors for Data , Error , Fetching and NotFound . Useful for pattern matching to render conditional UI. |
executeMutation |
(~myVar1, ~myVar2, ..., ~context=option(UrqlClient.ClientTypes.partialOperationContext)=?, ()) => Js.Promise.t(Client.ClientTypes.operationResult) |
A function for imperatively executing the mutation, which accepts all the variables of your mutation as named arguments. Also accepts an optional partialOperationContext using the labeled argument context . You must use a final positional unit argument, () , to indicate that you've finished applying the function. |
open ReasonUrql;
open Hooks;
module GetAllDogs = [%graphql {|
query dogs {
dogs {
name
breed
likes
}
}
|}];
module LikeDog = [%graphql
{|
mutation likeDog($key: ID!) {
likeDog(key: $key) {
likes
}
}
|}
];
[@react.component]
let make = () => {
let ({ response }, _) = useQuery(~request=GetAllDogs.make(), ());
let (_, executeMutation) = useDynamicMutation(LikeDog.definition);
switch (response) {
| Data(d) => {
<button
onClick={
_e => executeMutation(
~key=d##dogs[0]##id,
~context=Some(
Client.ClientTypes.partialOperationContext(~partialOpFetchPolicy=`NetworkOnly),
()
),
()
) |> ignore}
>
"Like The First Dog!"->React.string
</button>
}
| _ => React.null
}
}
Check out examples/3-mutation
to see an example of using the useDynamicMutation
hook.
useSubscription
allows you to execute a GraphQL subscription. You can accumulate the results of executing subscriptions by passing a handler
function to useSubscription
.
If using the useSubscription
hook, be sure your client is configured with the subscriptionExchange
.
Argument | Type | Description |
---|---|---|
request |
UrqlTypes.request |
The graphql_ppx request representing your subscription. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
handler |
Hooks.handler |
Optional. A variant type to allow for proper type inference of accumulated subscription data. A handler function allows you to accumulate subscription responses in the data field of the returned state record. |
useSubscription
returns the result of executing your GraphQL subscription as a record of type, result
.
Return Value | Type | Description |
---|---|---|
result |
UrqlTypes.hookResponse('response) |
A record containing fields for fetching , data , error , and response . response is a variant containing constructors for Data , Error , Fetching and NotFound . Useful for pattern matching to render conditional UI. |
open ReasonUrql;
open Hooks;
module SubscribeRandomInt = [%graphql
{|
subscription subscribeNumbers {
newNumber @bsDecoder(fn: "string_of_int")
}
|}
];
/* Accumulate subscriptions as new values arrive from your GraphQL endpoint. */
let handler = (prevSubscriptions, subscription) => {
switch (prevSubscriptions) {
| Some(subs) => Array.append(subs, [|subscription|])
| None => [|subscription|]
};
};
[@react.component]
let make = () => {
let {response} =
useSubscription(
~request=SubscribeRandomInt.make(),
~handler=Handler(handler)
);
switch (response) {
| Fetching => <div> "Loading"->React.string </div>
| Data(d) =>
d
|> Array.map(
(datum) =>
<circle
cx=datum##newNumber
cy=datum##newNumber
stroke="#222"
fill="none"
r="5"
/>,
)
|> React.array
| Error(_e) => <div> "Error"->React.string </div>
| NotFound => <div> "NotFound"->React.string </div>
}
}
Check out examples/5-subscription
to see an example of using the useSubscription
hook.
useClient
allows you to access your urql
client instance anywhere within your React component tree.
Return Value | Type | Description |
---|---|---|
client |
Client.t |
The urql client instance for your application. |
open ReasonUrql;
open Hooks;
[@react.component]
let make = () => {
let client = useClient();
<div> "You can now use your client!"->React.string </div>
}
The Query
allows you to query your GraphQL API and render UI with the returned data. It is a render prop component alternative to the useQuery
hook.
Prop | Type | Description |
---|---|---|
request |
UrqlTypes.request |
The graphql_ppx request representing your query. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
requestPolicy |
option(UrqlTypes.requestPolicy) |
Optional. The request policy to use to execute the query. Defaults to "cache-first" . |
pause |
option(bool) |
Optional. A boolean flag instructing Query to pause execution of the subsequent query operation. |
context |
option(Client.ClientTypes.partialOperationContext) |
Optional. A partial operation context object for modifying the execution parameters of this particular query (i.e. using different fetchOptions or a different url ). |
pollInterval |
option(int) |
Optional. Instructs the hook to reexecute the query every pollInterval milliseconds. |
Prop | Type | Description |
---|---|---|
fetching |
bool |
A boolean flag to indicate if the request is currently executing. |
data |
'response |
The data returned by your GraphQL API. |
error |
Error.combinedError |
The error(s), if any, returned by the GraphQL operation. |
executeQuery |
(~context: option(UrqlClient.ClientTypes.partialOperationContext), unit) => unit |
A callback to imperatively re-execute the query operation. Accepts a partial operation context to modify execution of the query. |
response |
UrqlTypes.response('response) |
A variant containing constructors for Data , Error , Fetching and NotFound . Useful for pattern matching to render conditional UI. |
open ReasonUrql;
module GetPokémon = [%graphql
{|
query pokemon($name: String!) {
pokemon(name: $name) {
name
classification
image
}
}
|}
];
let request = GetPokémon.make(~name="Abra", ());
[@react.component]
let make = () => {
<Query request>
{...({ response, executeQuery }) => {
switch (response) {
| Fetching => <div> "Loading"->React.string </div>
| Data(d) =>
<div>
<img src=d##pokemon##image>
<span> d##pokemon##name </span>
<span> d##pokemon##classification </span>
<button onClick={_event => executeQuery() |> ignore}>
{j|Refetch data for $d##pokemon##name|j} -> React.string
</button>
</div>
| Error(_e) => <div> "Error"->React.string </div>
| NotFound => <div> "NotFound"->React.string </div>
}
}}
</Query>
}
Check out examples/2-query
to see an example of using the Query
component.
The Mutation
component allows you to imperatively execute mutations. Use this component to access the executeMutation
function, which allows you to imperatively execute GraphQL mutations.
Prop | Type | Description |
---|---|---|
request |
UrqlTypes.request |
The graphql_ppx request representing your mutation. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
Prop | Type | Description |
---|---|---|
fetching |
bool |
A boolean flag to indicate if the request is currently executing. |
data |
'response |
The data returned by your GraphQL API. |
error |
CombinedError.combinedError |
The error(s), if any, returned by the GraphQL operation. |
executeMutation |
(~context: option(Client.ClientTypes.partialOperationContext), unit) => Js.Promise.t(Client.ClientTypes.operationResult) |
A callback to imperatively execute the associated GraphQL mutation. Accepts a partial operation context for altering the execution parameters of the mutation. |
response |
UrqlTypes.response('response) |
A variant containing constructors for Data , Error , Fetching and NotFound . Useful for pattern matching to render conditional UI. |
open ReasonUrql;
module LikeDog = [%graphql
{|
mutation likeDog($key: ID!) {
likeDog(key: $key) {
likes
}
}
|}
];
let request = GetAllDogs.make(~key="VmeRTX7j-", ());
[@react.component]
let make = () => {
<Mutation request>
{...({ executeMutation }) => {
<button onClick={_e => executeMutation() |> ignore}>
"Click Me to Execute the Mutation"->React.string
</button>
}}
</Mutation>
}
Check out examples/3-mutation
to see an example of using the Mutation
component.
The Subscription
component allows you to subscribe to GraphQL subscriptions emitted by your API. Use this component to render UI with realtime data. If you want to accumulate subscriptions, use the SubscriptionWithHandler
component.
If using the Subscription
component, be sure your client is configured with the subscriptionExchange
.
Prop | Type | Description |
---|---|---|
request |
UrqlTypes.request |
The graphql_ppx request representing your subscription. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
Prop | Type | Description |
---|---|---|
fetching |
bool |
A boolean flag to indicate if the request is currently executing. |
data |
'response |
The data returned by your GraphQL API. |
error |
Error.combinedError |
The error(s), if any, returned by the GraphQL operation. |
response |
UrqlTypes.response('response) |
A variant containing constructors for Data , Error , Fetching and NotFound . Useful for pattern matching to render conditional UI. |
open ReasonUrql;
module SubscribeMessages = [%graphql
{|
subscription subscribeMessages {
newMessage {
id
message
}
}
|}
];
let request = SubscribeMessages.make();
[@react.component]
let make = () => {
<Subscription request>
...{({response}) =>
switch (response) {
| Fetching => <div> "Loading"->React.string </div>
| Data(d) =>
<div>
{js|The most recent message is: $d##newMessage##message|js}->React.string
</div>
| Error(_e) => <div> "Error"->React.string </div>
| NotFound => <div> "NotFound"->React.string </div>
}
}
</Subscription>
};
The SubscriptionWithHandler
component is identitcal to the Subscription
component, except that it allows you to pass an additional handler
prop to accumulate subscriptions as they are returned from your GraphQL API.
If using the SubscriptionWithHandler
component, be sure your client is configured with the subscriptionExchange
.
Prop | Type | Description |
---|---|---|
request |
UrqlTypes.request |
The graphql_ppx request representing your subscription. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
handler |
(option('acc), 'response) => 'acc) |
A function that receives arguments for previous subscriptions and the current subscription and accumulates subscriptions. |
Prop | Type | Description |
---|---|---|
fetching |
bool |
A boolean flag to indicate if the request is currently executing. |
data |
'response |
The data returned by your GraphQL API. |
error |
Error.combinedError |
The error(s), if any, returned by the GraphQL operation. |
response |
UrqlTypes.response('response) |
A variant containing constructors for Data , Error , Fetching and NotFound . Useful for pattern matching to render conditional UI. |
open ReasonUrql;
module SubscribeRandomInt = [%graphql
{|
subscription subscribeNumbers {
newNumber @bsDecoder(fn: "string_of_int")
}
|}
];
let request = SubscribeRandomInt.make();
/* Accumulate subscriptions as new values arrive from your GraphQL endpoint. */
let handler = (prevSubscriptions, subscription) => {
switch (prevSubscriptions) {
| Some(subs) => Array.append(subs, [|subscription|])
| None => [|subscription|]
};
};
[@react.component]
let make = () => {
<SubscriptionWithHandler request handler>
...{({ response }) =>
switch (response) {
| Fetching => <div> "Loading"->React.string </div>
| Data(d) =>
d
|> Array.map(
(datum) =>
<circle
cx=datum##newNumber
cy=datum##newNumber
stroke="#222"
fill="none"
r="5"
/>,
)
|> React.array
| Error(_e) => <div> "Error"->React.string </div>
| NotFound => <div> "NotFound"->React.string </div>
}
}
</SubscriptionWithHandler>
}
The Provider
's responsibility is to pass the urql
client instance down to Query
, Mutation
, Subscription
, and SubscriptionWithHandler
components or useQuery
, useMutation
, and useSubcription
hooks through context. Wrap the root of your application with Provider
.
Prop | Type | Description |
---|---|---|
value |
Client.t |
The urql client instance. |
open ReasonUrql;
let client = Client.make(~url="https://localhost:3000/graphql", ());
ReactDOMRe.renderToElementWithId(<Provider value=client><App /></Provider>, "root");
The client is the central orchestrator of reason-urql
, and is responsible for executing queries, mutations, and subscriptions passed to useQuery
, useMutation
, and useSubscription
hooks or to the Query
, Mutation
, Subscription
, and SubscriptionWithHandler
components.
To create a client, simply call the make
function from the Client
module.
open ReasonUrql;
let client = Client.make(~url="https://localhost:3000/graphql", ());
The client optionally accepts a fetchOptions
argument for passing additional properties to fetch
requests (i.e. authorization headers) and an exchanges
argument for customizing the exchanges that operations are passed through.
Instantiate an urql
client instance. By default, urql
will execute requests with the following already in place if no configurations for fetchOptions
or exchanges
are provided:
- A
content-type
header ofapplication/json
. POST
as the HTTP method used to execute all operations.- The default exchanges.
Argument | Type | Description |
---|---|---|
url |
string |
The url of your GraphQL API. |
fetchOptions |
option(Client.fetchOptions)=? |
Optional. A variant type representing fetch options to be used by your client. You can pass your fetchOptions as a plain Fetch.requestInit by wrapping it in Client.FetchOpts , or instantiate it dynamically in a function wrapped by Client.FetchFn . |
exchanges |
option(array(Exchanges.exchange))=? |
Optional. The array of exchanges to be used by your client. |
suspense |
option(bool) |
Optional. A flag activating the experimental React suspense mode, which can be used during server-side rendering to prefetch data. Defaults to false . |
fetch |
option(fetchImpl('a)) |
Optional. A custom fetch implementation to use in lieu of window.fetch . For now, see __tests__/UrqlClient_test.re for examples of how to use this option. |
requestPolicy |
option(UrqlTypes.requestPolicy) |
Optional. The default requestPolicy to use for all outgoing requests. Defaults to `CacheFirst. |
Returns an instance of the urql
client of type Client.t
. This can then be passed to your root Provider
component.
Create a client with just a url
.
open ReasonUrql;
let client = Client.make(~url="https://localhost:3000/graphql", ());
Create a client with fetchOptions
.
open ReasonUrql;
let fetchOptions =
Client.FetchOpts(Fetch.RequestInit.make(
~method_=Post,
~headers=Fetch.HeadersInit.make({"Content-Type": "application/json"}),
(),
));
let client = Client.make(~url="https://localhost:3000/graphql", ~fetchOptions, ());
Create a client with exchanges
.
open ReasonUrql;
let client = Client.make(
~url="https://localhost:3000/graphql",
~exchanges=[|
Exchanges.debugExchange,
Exchanges.dedupExchange,
Exchanges.cacheExchange,
Exchanges.fetchExchange
|],
()
);
Create a client with a non-default requestPolicy.
let client = Client.make(
~url="https://localhost:3000/graphql",
~requestPolicy=`CacheAndNetwork,
()
);
Imperatively execute a GraphQL query operation.
Argument | Type | Description |
---|---|---|
client |
Client.t |
The urql client instance. |
request |
UrqlTypes.request |
The graphql_ppx request representing your query. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
opts |
option(Client.ClientTypes.partialOperationContext)=? |
Optional. Additional options to pass to the client to alter the execution parameters of the query. |
Returns a wonka
source
containing the results of executing the query. The result record has a variant type called response
with constructors for Data(d)
, Error(e)
, and NotFound
, in addition to data
and error
fields for accessing the raw response values if desired.
Return | Description |
---|---|
Wonka.Types.sourceT(ClientTypes.clientResponse('response)) |
A wonka source containing a record of the results of query execution. Use the response field on this record for pattern matching. |
open ReasonUrql;
let client = Client.make(~url="https://localhost:3000/graphql", ());
module GetAllDogs = [%graphql
{|
query dogs {
dogs {
name
breed
likes
}
}
|}
];
Client.executeQuery(~client, ~request=GetAllDogs.make(), ())
|> Wonka.subscribe((. result) => {
switch(result.response) {
| Data(d) => /* Access data returned from executing the request. */
| Error(e) => /* Access any errors returned from executing the request. */
| NotFound => /* Fallback if neither Data nor Error return information. */
}
});
The same as Client.executeQuery
, but returns a Promise
rather than a wonka
source
.
Argument | Type | Description |
---|---|---|
client |
Client.t |
The urql client instance. |
request |
UrqlTypes.request |
The graphql_ppx request representing your query. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
opts |
option(Client.ClientTypes.partialOperationContext)=? |
Optional. Additional options to pass to the client to alter the execution parameters of the query. |
Returns a Js.Promise.t
containing the results of executing the query. The result record has a variant type called response
with constructors for Data(d)
, Error(e)
, and NotFound
, in addition to data
and error
fields for accessing the raw response values if desired.
Return | Description |
---|---|
Js.Promise.t(ClientTypes.clientResponse('response)) |
A Promise containing a record of the results of query execution. Use the response field on this record for pattern matching. |
open ReasonUrql;
let client = Client.make(~url="https://localhost:3000/graphql", ());
module GetAllDogs = [%graphql
{|
query dogs {
dogs {
name
breed
likes
}
}
|}
];
Client.query(~client, ~request=GetAllDogs.make(), ())
|> Js.Promise.then_((. result) => {
switch(result.response) {
| Data(d) => /* Access data returned from executing the request. */
| Error(e) => /* Access any errors returned from executing the request. */
| NotFound => /* Fallback if neither Data nor Error return information. */
}
});
Execute a GraphQL mutation operation.
Argument | Type | Description |
---|---|---|
client |
Client.t |
The urql client instance. |
request |
UrqlTypes.request |
The graphql_ppx request representing your mutation. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
opts |
option(Client.ClientTypes.partialOperationContext)=? |
Optional. Additional options to pass to the client to alter the execution parameters of the mutation. |
Returns a wonka
source
containing the results of executing the mutation. The result record has a variant type called response
with constructors for Data(d)
, Error(e)
, and NotFound
, in addition to data
and error
fields for accessing the raw response values if desired.
Return | Description |
---|---|
Wonka.Types.sourceT(ClientTypes.clientResponse('response)) |
A wonka source containing a record of the results of mutation execution. Use the response field on this record for pattern matching. |
open ReasonUrql;
let client = Client.make(~url="https://localhost:3000/graphql", ());
module LikeDog = [%graphql
{|
mutation likeDog($key: ID!) {
likeDog(key: $key) {
name
breed
likes
}
}
|}
];
Client.executeMutation(~client, ~request=LikeDog.make(~key="VmeRTX7j-", ()), ())
|> Wonka.subscribe((. result) => {
switch(result.response) {
| Data(d) => /* Access data returned from executing the request. */
| Error(e) => /* Access any errors returned from executing the request. */
| NotFound => /* Fallback if neither Data nor Error return information. */
}
});
The same as Client.executeMutation
, but returns a Promise
rather than a wonka
source
.
Argument | Type | Description |
---|---|---|
client |
Client.t |
The urql client instance. |
request |
UrqlTypes.request |
The graphql_ppx request representing your query. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
opts |
option(Client.ClientTypes.partialOperationContext)=? |
Optional. Additional options to pass to the client to alter the execution parameters of the mutation. |
Returns a Js.Promise.t
containing the results of executing the mutation. The result record has a variant type called response
with constructors for Data(d)
, Error(e)
, and NotFound
, in addition to data
and error
fields for accessing the raw response values if desired.
Return | Description |
---|---|
Js.Promise.t(ClientTypes.clientResponse('response)) |
A Promise containing a record of the results of mutation execution. Use the response field on this record for pattern matching. |
open ReasonUrql;
let client = Client.make(~url="https://localhost:3000/graphql", ());
module LikeDog = [%graphql
{|
mutation likeDog($key: ID!) {
likeDog(key: $key) {
name
breed
likes
}
}
|}
];
Client.mutation(~client, ~request=LikeDog.make(~key="VmeRTX7j-", ()), ())
|> Js.Promise.then_((. result) => {
switch(result.response) {
| Data(d) => /* Access data returned from executing the request. */
| Error(e) => /* Access any errors returned from executing the request. */
| NotFound => /* Fallback if neither Data nor Error return information. */
}
});
Execute a GraphQL subscription operation. If using the executeSubscription
method, be sure your client is configured with the subscriptionExchange
.
Argument | Type | Description |
---|---|---|
client |
Client.t |
The urql client instance. |
request |
UrqlTypes.graphqlRequest |
The graphql_ppx request representing your subscription. Generated by calling .make() on the graphql_ppx module. If you're not using graphql_ppx , pass a Js.t of the following shape: {. "query": string, "variables": Js.Json.t, "parse": Js.Json.t => 'response } |
opts |
option(Client.ClientTypes.partialOperationContext)=? |
Optional. Additional options to pass to the operation. |
open ReasonUrql;
module SubscribeMessages = [%graphql
{|
subscription subscribeMessages {
newMessage {
id
message
}
}
|}
];
Client.executeSubscription(~client, ~request=SubscribeMessages.make(), ())
|> Wonka.subscribe((. result) => {
switch(result.response) {
| Data(d) => /* Access data returned from executing the request. */
| Error(e) => /* Access any errors returned from executing the request. */
| NotFound => /* Fallback if neither Data nor Error return information. */
}
});
Exchanges are the mechanism by which urql
modifies requests before they are sent to your GraphQL API and alters responses as they are received. If you want to add some additional functionality to your GraphQL operations, this is a great place to do that. The following exchanges are provided out of the box with urql
.
The cacheExchange
provides basic caching support for your GraphQL operations. It is of type Exchanges.exchange
.
The dedupExchange
will deduplicate pending operations waiting for a response. For example, if a user attempts to execute the same query by clicking a button in rapid succession, the dedupExchange
will filter these events to a single request. It is of type Exchanges.exchange
.
The fetchExchange
is responsible for actually sending your request to your GraphQL API and handling the response. It is of type Exchanges.exchange
.
The above three exchanges make up urql
's defaultExchanges
. When you create a client in reason-urql
these exchanges are already applied by default. If you specify an exchanges
array, be sure to include the specific exchanges you need. You almost always want the defaultExchanges
, so make sure to include them using Array.concat
or Array.append
.
open ReasonUrql;
let client = Client.make(
~url="https://mygraphql.com/api",
~exchanges=Array.append([|myCustomExchange|], Exchanges.defaultExchanges
);
The debugExchange
is useful for tracking how operations are passing through the exchanges pipeline. It simply logs all incoming and outgoing operations to the console. Be sure to remove this in production! It is of type Exchanges.exchange
.
The subscriptionExchange
should be used in the event that you intend to support GraphQL subscriptions in your application through use of useSubscription
, the Subscription
or SubscriptionWithHandler
components, or the client's executeSubscription
method.
In order to use the subscriptionExchange
, you'll need to do a little bit of setup. Specifically, you'll need to configure a subscription client of some kind that will handle the websocket connection to your GraphQL API. In examples/5-subscription
we have some simple bindings to subscriptions-transport-ws
that allow us to use this protocol (which is supported by Apollo). Here's an example of how to set everything up:
/* Create the subscriptionClient using APIs from your subscription client of choice.
In this case we use custom bindings to SubscriptionsTransportWS. */
let subscriptionClient =
SubscriptionsTransportWS.subscriptionClient(
~url="ws://localhost:4001/graphql",
~subscriptionClientConfig=SubscriptionsTransportWS.subscriptionClientConfig(),
);
/* Implement the forwardSubscription function. This tells urql how to handle
incoming operations of operationType 'subscription'. */
let forwardSubscription = operation => subscriptionClient##request(operation);
/* Confirgure options for urql's subscriptionExchange. */
let subscriptionExchangeOpts =
Exchanges.subscriptionExchangeOpts(~forwardSubscription);
/* Create the subscriptionExchange. */
let subscriptionExchange =
Exchanges.subscriptionExchange(subscriptionExchangeOpts);
/* Include the subscriptionExchange in your client's exchanges array. */
let client = Client.make(
~url="https://localhost:3000/graphql",
~exchanges=Array.append(Exchanges.defaultExchanges, [|subscriptionExchange|]),
()
);
The ssrExchange
is currently experimental. It acceps a single optional argument, ~ssrExchangeOpts
, a bs.deriving abstract
that accepts two properties – ~initialState
(which populates the server-side rendered data with a rehydrated cache) and ~isClient
, which tells the exchange whether it is running on the client or the server.
If using the ssrExchange
, it should be placed after any caching exchanges, like cacheExchange
, but before any asynchronous exchanges, like fetchExchange
.
open ReasonUrql;
let ssrCache = Exchanges.ssrExchange();
let client = Client.make(
~url="http://localhost:3000",
~exchanges=[|
Exchanges.dedupExchange,
Exchanges.cacheExchange,
ssrCache,
Exchanges.fetchExchange
|],
()
);
The resulting object returned from creating the ssrExchange
has two methods available on it – extractData
and restoreData
. extractData
is typically used on the server-side to extract data returned from your GrqphQL requests after they've been executed on the server.
let ssrCache = Exchanges.ssrExchange(~ssrExchangeOpts, ());
/* Extract data from the ssrCache. */
let extractedData = Exchanges.extractData(~exchange=ssrCache);
restoreData
is typically used to rehydrate the client with data from the server. The restore
argument is what allows you to reference the data returned from the server to the client.
let ssrCache = Exchanges.ssrExchange(~ssrExchangeOpts, ());
/* Extract data from the ssrCache. */
let extractedData = Exchanges.restoreData(~exchange=ssrCache, ~restore=urqlData);
This part of the API is still quite experimental, as server-side rendering in Reason with NextJS is still in its infancy. Use with caution. For more information, read urql
's server-side rendering guide here. To see an example of server-side rendering with reason-urql
, check out our reason-urql-ssr
example.
composeExchanges
is a helper function that will compose a single exchange function from an array of exchanges. Operations will be run through the provided exchanges in the order that they were provided to composeExchanges
.
Errors in reason-urql
are handed to your components and hooks via a record of type CombinedError.t
. The record has the following type:
type t = {
networkError: option(Js.Exn.t),
graphQLErrors: option(array(graphQLError)),
response: option(Fetch.response),
message: string,
};
In this case, networkError
returns the original JavaScript error thrown if a network error was encountered. graphQLErrors
represent an array
of errors of type graphQLError
. These represent the errors encountered in the validation or execution stages of interacting with your GraphQL API. response
is the raw response
object returned by fetch
. message
is a stringified version of either the networkError
or the graphQLErrors
– networkError
will take precedence.
The easiest way to interact with CombinedError
is through the message
field on the CombinedError.t
record. If you just want to display the error message to your user, or operate directly on the error string, simply do the following:
switch (response) {
| Error(e) => <div> e.message->React.string </div>
| _ => <div />
}
Depending on the types of errors you get from your GraphQL API, you may want to do different things. Here's an example showing how to handle networkError
s and graphQLErrors
indepedently.
let ({ response }, _) = useQuery(~request, ());
switch (response) {
| Error(e) =>
switch (e) {
| {networkError: Some(ne)} =>
<div>
{ne
->Js.Exn.message
->Belt.Option.getWithDefault("Network error")
->React.string}
</div>
| {graphQLErrors: Some(gqle)} =>
<div>
{gqle
|> Array.to_list
|> List.map(e => {
let msg =
Belt.Option.getWithDefault(
Js.Nullable.toOption(CombinedError.messageGet(e)),
"GraphQL error",
);
"[GraphQLError: " ++ msg ++ "]";
})
|> String.concat(", ")
|> React.string}
</div>
| _ => <div> "Unknown error."->React.string </div>
}
}
| _ => <div />
}