A Relay Network layer built on ky.
Features:
- Queries over
GET, mutations overPOST - File uploads via the GraphQL multipart request spec
- Incremental delivery (
@defer/@stream) overmultipart/mixed, normalized to Relay-compatible payloads - Configurable retries, timeouts, and logout handling
- Request/response/error hooks passed through to
ky
npm add @stackworx/relay-network ky relay-runtimeky and relay-runtime are peer dependencies.
import {Network} from "relay-runtime";
import {createFetchQuery} from "@stackworx/relay-network";
const network = Network.create(
createFetchQuery({
url: "http://localhost/graphql",
// Optional
timeout: 10000,
// Optional. Queries are retried; mutations never are.
retry: {
statusCodes: [503],
methods: ["get"],
limit: 2,
},
// Optional. Return true when the response means the user should be logged
// out. Default: response.status === 403
logoutCheck(response) {
return response.status === 403;
},
// Optional. React to expired credentials, e.g. clear the store or tokens.
async handleLogout() {
// ...
},
}),
);| Option | Type | Description |
|---|---|---|
url |
string | (() => Promise<string>) |
GraphQL endpoint, or a function resolving to one. |
headers |
Record<string, string | undefined> | ((request) => Promise<...>) |
Static headers, or a function producing them per request. |
timeout |
ky timeout |
Request timeout. |
retry |
ky retry |
Retry config. Applied to queries only, never mutations. |
logoutCheck |
(response: Response) => boolean |
Decide whether a response means the user should be logged out. Default: status === 403. |
handleLogout |
() => Promise<void> | void |
Called when logoutCheck returns true. |
deleteDataIfError |
boolean |
When a payload has both data and errors, drop data so Relay routes it to onError. Useful for servers that return {} on failed mutations. |
allowApplicationJsonContentType |
boolean |
Accept application/json responses in addition to application/graphql-response+json. |
hooks |
ky Hooks |
ky lifecycle hooks (beforeRequest, afterResponse, beforeError, ...). Merged ahead of the built-in logout beforeError hook. |
Some GraphQL servers send incremental delivery payloads in the RFC-style shape:
{
"incremental": [
{
"data": {"exportName": "Kolomela 63.5%, 8mm Fine Ore"},
"label": "test",
"path": ["products", 1]
}
],
"hasNext": false
}Relay Runtime (17.x) treats a payload as an incremental patch only if it has
top-level label and path. If the RFC-style payload is forwarded as-is, Relay
can warn that there was "No data returned" (because there is no top-level
data).
This library normalizes the RFC-style payload into Relay-compatible patch
payloads before calling sink.next(...):
{
"data": {"exportName": "Kolomela 63.5%, 8mm Fine Ore"},
"label": "test",
"path": ["products", 1]
}When mocking multipart/mixed responses with MSW, see
mswjs/msw#1388 (comment).
Contributions are welcome! See CONTRIBUTING.md.
MIT © Stackworx