Skip to content

Commit b3a104f

Browse files
committed
Add additional API information to README
Signed-off-by: Matthew Peveler <matt.peveler@gmail.com>
1 parent 918752f commit b3a104f

File tree

2 files changed

+144
-3
lines changed

2 files changed

+144
-3
lines changed

README.md

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
An [Apollo Link](https://www.apollographql.com/docs/link/) that aborts requests that aren't completed within a specified timeout period. Note that timeouts are enforced for query and mutation operations only (not subscriptions).
44

55
## Installation
6-
```
6+
7+
```bash
78
npm install apollo-link-timeout
89
```
10+
911
or
10-
```
12+
13+
```bash
1114
yarn add apollo-link-timeout
1215
```
1316

1417
## Usage
18+
1519
```javascript
1620
import ApolloLinkTimeout from 'apollo-link-timeout';
1721
import { createHttpLink } from 'apollo-link-http';
@@ -29,7 +33,7 @@ const apolloClient = new ApolloClient({ link: timeoutHttpLink });
2933

3034
// use timeout-enabled Apollo client...
3135

32-
// Override timeout from any query
36+
// Override timeout from any query
3337
<Query
3438
query={SOME_QUERY}
3539
variables={{
@@ -41,4 +45,61 @@ const apolloClient = new ApolloClient({ link: timeoutHttpLink });
4145
// ...
4246
```
4347

48+
## API
49+
50+
**`new ApolloLinkTimeout(timeout?, statusCode?)`**
51+
52+
Creates a new TimeoutLink instance that aborts requests if the timeout expires before the response is received.
53+
54+
**Parameters:**
55+
56+
- `timeout` (optional): The timeout in milliseconds for the request. Defaults to 15000ms (15 seconds) if omitted.
57+
- `statusCode` (optional): The HTTP status code to return when a timeout occurs. Defaults to 408 (Request Timeout) if omitted.
58+
59+
## Overriding Timeout Per Operation
60+
61+
You can override the default timeout for individual operations by setting a `timeout` value in the operation context:
62+
63+
```javascript
64+
// Override timeout in a query
65+
<Query
66+
query={SOME_QUERY}
67+
variables={{
68+
someVar1: "foo",
69+
someVar2: "bar",
70+
}}
71+
context={{ timeout: 3000 }} // 3 second timeout for this query
72+
>
73+
// ...
74+
</Query>
75+
76+
77+
// Or when calling the client directly
78+
apolloClient.query({
79+
query: SOME_QUERY,
80+
context: { timeout: 5000 } // 5 second timeout
81+
});
82+
83+
// Or via a prior link
84+
const link = new ApolloLink((operation, forward) => {
85+
operation.setContext({ timeout: 5000 });
86+
});
87+
link.concat(timeoutLink);
88+
```
89+
90+
The timeout resolution follows this priority: operation-level context timeout > link-level timeout > default (15000ms).
91+
92+
## Disabling Timeout
93+
94+
To disable the timeout for a specific operation, set the timeout to a negative value in the operation context:
95+
96+
```javascript
97+
apolloClient.query({
98+
query: SOME_QUERY,
99+
context: { timeout: -1 } // Disable timeout for this query
100+
});
101+
```
102+
103+
When a negative timeout is provided, the timeout link will be skipped and the operation will proceed without any timeout enforcement.
104+
44105
See [Apollo documentation](https://www.apollographql.com/client) for information on using the Apollo client.

__tests__/timeoutLink.test.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,54 @@ test('configured short value through context time out', done => {
100100
});
101101
});
102102

103+
test('configured value through prior link does not time out', done => {
104+
delay = 200;
105+
const configured = 500;
106+
107+
const configLink = new ApolloLink((operation, forward) => {
108+
operation.setContext({ timeout: configured });
109+
return forward(operation);
110+
});
111+
112+
const testLink = configLink.concat(timeoutLink).concat(mockLink);
113+
114+
execute(testLink, { query }).subscribe({
115+
next() {
116+
expect(called).toBe(1);
117+
done();
118+
},
119+
error() {
120+
expect('error called').toBeFalsy();
121+
done();
122+
}
123+
});
124+
});
125+
126+
test('configured short value through prior link time out', done => {
127+
delay = 200;
128+
const configured = 100;
129+
130+
const configLink = new ApolloLink((operation, forward) => {
131+
operation.setContext({ timeout: configured });
132+
return forward(operation);
133+
});
134+
135+
const testLink = configLink.concat(timeoutLink).concat(mockLink);
136+
137+
execute(testLink, { query }).subscribe({
138+
next() {
139+
expect('next called').toBeFalsy();
140+
done();
141+
},
142+
error(error) {
143+
expect(error.message).toEqual('Timeout exceeded');
144+
expect(error.timeout).toEqual(configured);
145+
expect(error.statusCode).toEqual(408);
146+
done();
147+
}
148+
});
149+
});
150+
103151
test('aborted request does not timeout', done => {
104152
delay = 200;
105153

@@ -120,6 +168,38 @@ test('aborted request does not timeout', done => {
120168
});
121169
});
122170

171+
test('negative timeout via constructor disables timeout', done => {
172+
delay = 150;
173+
174+
const testLink = new TimeoutLink(-1).concat(mockLink);
175+
176+
execute(testLink, { query }).subscribe({
177+
next() {
178+
expect(called).toBe(1);
179+
done();
180+
},
181+
error() {
182+
expect('error called').toBeFalsy();
183+
done();
184+
}
185+
});
186+
});
187+
188+
test('negative timeout via context disables timeout', done => {
189+
delay = 150;
190+
191+
execute(link, { query, context: { timeout: -1 } }).subscribe({
192+
next() {
193+
expect(called).toBe(1);
194+
done();
195+
},
196+
error() {
197+
expect('error called').toBeFalsy();
198+
done();
199+
}
200+
});
201+
});
202+
123203
if (nodeMajor >= 20) {
124204
test("HTTP multipart subscription stops when unsubscribed", (done) => {
125205
const subscription = gql`

0 commit comments

Comments
 (0)