Skip to content

Commit

Permalink
feat(exchanges): add binding for @urql/exchange-request-policy (#247)
Browse files Browse the repository at this point in the history
  • Loading branch information
parkerziegler authored Jan 5, 2021
1 parent 2cb0205 commit 9b6337e
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 0 deletions.
29 changes: 29 additions & 0 deletions __tests__/Client_test.res
Original file line number Diff line number Diff line change
Expand Up @@ -241,5 +241,34 @@ describe("Client", () => {
})
})
})

describe("requestPolicyExchange", () => {
it("should return None for all requestPolicyExchange options if unspecified", () => {
let requestPolicyExchangeOptions = Client.Exchanges.makeRequestPolicyExchangeOptions()

open Expect
expect(requestPolicyExchangeOptions) |> toEqual({
Client.Exchanges.shouldUpgrade: None,
ttl: None,
})
})

it("should apply any specified options to the requestPolicyExchange", () => {
let shouldUpgrade = (operation: Types.operation) =>
operation.context.requestPolicy !== #CacheOnly

let requestPolicyExchangeOptions = Client.Exchanges.makeRequestPolicyExchangeOptions(
~shouldUpgrade,
~ttl=2000,
(),
)

open Expect
expect(requestPolicyExchangeOptions) |> toEqual({
Client.Exchanges.shouldUpgrade: Some(shouldUpgrade),
ttl: Some(2000),
})
})
})
})
})
41 changes: 41 additions & 0 deletions docs/exchanges.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,47 @@ let client = Client.make(

Read more on the `retryExchange` [here](https://formidable.com/open-source/urql/docs/advanced/retry-operations/).

### `requestPolicyExchange`

The `requestPolicyExchange` allows `reason-urql` to automatically upgrade an operation's `requestPolicy` on a time-to-live basis. When the specified TTL has elapsed, `reason-urql` will either:

- Upgrade the `requestPolicy` of the operation to `cache-and-network` if no `shouldUpgrade` callback is specified, or:
- Run the `shouldUpgrade` function to determine whether or not to upgrade the specific operation.

To use the `requestPolicyExchange`, add the package to your dependencies:

```sh
yarn add @urql/exchange-request-policy
```

Then, add the exchange to your array of `exchanges`, specifying the options you want to configure:

```rescript
open ReasonUrql
let shouldUpgrade = (operation: Types.operation) =>
operation.context.requestPolicy !== #CacheOnly
let requestPolicyExchangeOptions = Client.Exchanges.makeRequestPolicyExchangeOptions(
~shouldUpgrade,
~ttl=2000,
(),
)
let client = Client.make(
~url="http://localhost:3000",
~exchanges=[
Client.Exchanges.dedupExchange,
Client.Exchanges.cacheExchange,
Client.Exchanges.requestPolicyExchange(requestPolicyExchangeOptions),
Client.Exchanges.fetchExchange
],
()
)
```

Read more about the `requestPolicyExchange` [here](https://github.com/FormidableLabs/urql/tree/main/exchanges/request-policy).

## Custom Exchanges

`reason-urql` also allows you to write your own exchanges to modify outgoing GraphQL requests and incoming responses. To read up on the basics of exchanges, check out the excellent [`urql` documentation](https://formidable.com/open-source/urql/docs/concepts/exchanges/).
Expand Down
13 changes: 13 additions & 0 deletions src/Client.res
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,19 @@ module Exchanges = {
@module("@urql/exchange-retry")
external retryExchange: retryExchangeOptions => t = "retryExchange"

type requestPolicyExchangeOptions = {
shouldUpgrade: option<Types.operation => bool>,
ttl: option<int>,
}

let makeRequestPolicyExchangeOptions = (~shouldUpgrade=?, ~ttl=?, ()) => {
shouldUpgrade: shouldUpgrade,
ttl: ttl,
}

@module("@urql/exchange-request-policy")
external requestPolicyExchange: requestPolicyExchangeOptions => t = "requestPolicyExchange"

/* Specific types for the subscriptionExchange. */
type observerLike<'value> = {
next: 'value => unit,
Expand Down
14 changes: 14 additions & 0 deletions src/Client.resi
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,20 @@ module Exchanges: {
@module("@urql/exchange-retry")
external retryExchange: retryExchangeOptions => t = "retryExchange"

type requestPolicyExchangeOptions = {
shouldUpgrade: option<Types.operation => bool>,
ttl: option<int>,
}

let makeRequestPolicyExchangeOptions: (
~shouldUpgrade: Types.operation => bool=?,
~ttl: int=?,
unit,
) => requestPolicyExchangeOptions

@module("@urql/exchange-request-policy")
external requestPolicyExchange: requestPolicyExchangeOptions => t = "requestPolicyExchange"

/* Specific types for the subscriptionExchange. */
type observerLike<'value> = {
next: 'value => unit,
Expand Down

0 comments on commit 9b6337e

Please sign in to comment.