Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(exchanges): add binding for @urql/exchange-request-policy #247

Merged
merged 1 commit into from
Jan 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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