Stateful Links

Links are created and shared between every request in your application. Some links may share state between requests to provided added functionality. The links are called stateful links and are written using the ApolloLink interface. The alternative way to write links is a stateless link.

Stateful links typically (though are not required to) overwrite the constructor of ApolloLink and are required to implement a request function with the same signature as a stateless link. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { ApolloLink } from 'apollo-link';

class OperationCountLink extends ApolloLink {
constructor() {
super();
this.operations = 0;
}
request(operation, forward) {
this.operations++
return forward(operation);
}
}

const link = new OperationCountLink();

It is important when managing stateful links where the request is being saved to implement a key value store for the requests. Otherwise, it is easy to accidentally override an in-flight request with another operation happening. Take for example a portion of the dedup link:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import { ApolloLink } from 'apollo-link';

export default class DedupLink extends ApolloLink {
private inFlightRequestObservables: {
[key: string]: Observable<FetchResult>;
};

constructor() {
super();
this.inFlightRequestObservables = {};
}

public request(
operation: Operation,
forward: NextLink,
): Observable<FetchResult> {
const key = operation.toKey();
if (!this.inFlightRequestObservables[key]) {
this.inFlightRequestObservables[key] = forward(operation);
}

return new Observable<FetchResult>(observer => {
const subscription = this.inFlightRequestObservables[key].subscribe({
next: (result) => {
delete this.inFlightRequestObservables[key];
observer.next(result);
},
error: error => {
delete this.inFlightRequestObservables[key];
observer.error(error);
},
complete: observer.complete.bind(observer),
});

return () => {
if (subscription) subscription.unsubscribe();
delete this.inFlightRequestObservables[key];
};
});
}
}

More commonly, stateful links are used for complex control flow like batching and deduplication of operations.

Edit on GitHub