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";constnetwork=Network.create(createFetchQuery({url: "http://localhost/graphql",// Optionaltimeout: 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 === 403logoutCheck(response){returnresponse.status===403;},// Optional. React to expired credentials, e.g. clear the store or tokens.asynchandleLogout(){// ...},}),);| 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 | kyHooks | 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