Skip to content

Commit 147f820

Browse files
feat: [GH-177] forward all cache options to key value cache (#185)
Added support to the `RESTDatasource` to be able to specify a custom cache set options type. The cache set options may need to be customized to include additional set options supported by the underlying key value cache implementation. --------- Co-authored-by: Hisham Ali <[email protected]>
1 parent 9f9f8ac commit 147f820

File tree

8 files changed

+202
-91
lines changed

8 files changed

+202
-91
lines changed

.changeset/plenty-cooks-bathe.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
'@apollo/datasource-rest': minor
3+
---
4+
5+
Added support to the RESTDatasource to be able to specify a custom cache set options type. The cache set options may need to be customized to include additional set options supported by the underlying key value cache implementation.
6+
7+
For example, if the [InMemoryLRUCache](https://github.com/apollographql/apollo-utils/blob/main/packages/keyValueCache/src/InMemoryLRUCache.ts) is being used to cache HTTP responses, then `noDisposeOnSet`, `noUpdateTTL`, etc cache options can be provided to the LRU cache:
8+
9+
```typescript
10+
import { InMemoryLRUCache } from '@apollo/utils.keyvaluecache';
11+
12+
interface CustomCacheOptions {
13+
ttl?: number;
14+
noDisposeOnSet?: boolean;
15+
}
16+
17+
class ExampleDataSource extends RESTDataSource<CustomCacheOptions> {
18+
override baseURL = 'https://api.example.com';
19+
20+
constructor() {
21+
super({ cache: new InMemoryLRUCache() });
22+
}
23+
24+
getData(id: number) {
25+
return this.get(`data/${id}`, {
26+
cacheOptions: { ttl: 3600, noDisposeOnSet: true },
27+
});
28+
}
29+
}
30+
```

package-lock.json

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
},
5555
"dependencies": {
5656
"@apollo/utils.fetcher": "^3.0.0",
57-
"@apollo/utils.keyvaluecache": "^3.0.0",
57+
"@apollo/utils.keyvaluecache": "^3.1.0",
5858
"@apollo/utils.logger": "^3.0.0",
5959
"@apollo/utils.withrequired": "^3.0.0",
6060
"@types/http-cache-semantics": "^4.0.1",

src/HTTPCache.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ interface ResponseWithCacheWritePromise {
3636
cacheWritePromise?: Promise<void>;
3737
}
3838

39-
export class HTTPCache {
40-
private keyValueCache: KeyValueCache;
39+
export class HTTPCache<CO extends CacheOptions = CacheOptions> {
40+
private keyValueCache: KeyValueCache<string, CO>;
4141
private httpFetch: Fetcher;
4242

4343
constructor(
44-
keyValueCache: KeyValueCache = new InMemoryLRUCache(),
44+
keyValueCache: KeyValueCache = new InMemoryLRUCache<string, CO>(),
4545
httpFetch: Fetcher = nodeFetch,
4646
) {
4747
this.keyValueCache = new PrefixingKeyValueCache(
@@ -57,12 +57,12 @@ export class HTTPCache {
5757
cache?: {
5858
cacheKey?: string;
5959
cacheOptions?:
60-
| CacheOptions
60+
| CO
6161
| ((
6262
url: string,
6363
response: FetcherResponse,
6464
request: RequestOptions,
65-
) => ValueOrPromise<CacheOptions | undefined>);
65+
) => ValueOrPromise<CO | undefined>);
6666
httpCacheSemanticsCachePolicyOptions?: HttpCacheSemanticsOptions;
6767
},
6868
): Promise<ResponseWithCacheWritePromise> {
@@ -189,12 +189,12 @@ export class HTTPCache {
189189
policy: SneakyCachePolicy,
190190
cacheKey: string,
191191
cacheOptions?:
192-
| CacheOptions
192+
| CO
193193
| ((
194194
url: string,
195195
response: FetcherResponse,
196196
request: RequestOptions,
197-
) => ValueOrPromise<CacheOptions | undefined>),
197+
) => ValueOrPromise<CO | undefined>),
198198
): Promise<ResponseWithCacheWritePromise> {
199199
if (typeof cacheOptions === 'function') {
200200
cacheOptions = await cacheOptions(url, response, request);
@@ -246,6 +246,7 @@ export class HTTPCache {
246246
cacheWritePromise: this.readResponseAndWriteToCache({
247247
response,
248248
policy,
249+
cacheOptions,
249250
ttl,
250251
ttlOverride,
251252
cacheKey,
@@ -256,12 +257,14 @@ export class HTTPCache {
256257
private async readResponseAndWriteToCache({
257258
response,
258259
policy,
260+
cacheOptions,
259261
ttl,
260262
ttlOverride,
261263
cacheKey,
262264
}: {
263265
response: FetcherResponse;
264266
policy: CachePolicy;
267+
cacheOptions?: CO;
265268
ttl: number | null | undefined;
266269
ttlOverride: number | undefined;
267270
cacheKey: string;
@@ -273,9 +276,11 @@ export class HTTPCache {
273276
body,
274277
});
275278

279+
// Set the value into the cache, and forward all the set cache option into the setter function
276280
await this.keyValueCache.set(cacheKey, entry, {
281+
...cacheOptions,
277282
ttl,
278-
});
283+
} as CO);
279284
}
280285
}
281286

0 commit comments

Comments
 (0)