Skip to content

Commit

Permalink
feat: [GH-177] forward all cache options to key value cache (#185)
Browse files Browse the repository at this point in the history
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 <hisham@otofacts.com>
  • Loading branch information
HishamAli81 and hisham-otofacts authored Sep 18, 2023
1 parent 9f9f8ac commit 147f820
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 91 deletions.
30 changes: 30 additions & 0 deletions .changeset/plenty-cooks-bathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
'@apollo/datasource-rest': minor
---

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.

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:

```typescript
import { InMemoryLRUCache } from '@apollo/utils.keyvaluecache';

interface CustomCacheOptions {
ttl?: number;
noDisposeOnSet?: boolean;
}

class ExampleDataSource extends RESTDataSource<CustomCacheOptions> {
override baseURL = 'https://api.example.com';

constructor() {
super({ cache: new InMemoryLRUCache() });
}

getData(id: number) {
return this.get(`data/${id}`, {
cacheOptions: { ttl: 3600, noDisposeOnSet: true },
});
}
}
```
30 changes: 15 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
},
"dependencies": {
"@apollo/utils.fetcher": "^3.0.0",
"@apollo/utils.keyvaluecache": "^3.0.0",
"@apollo/utils.keyvaluecache": "^3.1.0",
"@apollo/utils.logger": "^3.0.0",
"@apollo/utils.withrequired": "^3.0.0",
"@types/http-cache-semantics": "^4.0.1",
Expand Down
21 changes: 13 additions & 8 deletions src/HTTPCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ interface ResponseWithCacheWritePromise {
cacheWritePromise?: Promise<void>;
}

export class HTTPCache {
private keyValueCache: KeyValueCache;
export class HTTPCache<CO extends CacheOptions = CacheOptions> {
private keyValueCache: KeyValueCache<string, CO>;
private httpFetch: Fetcher;

constructor(
keyValueCache: KeyValueCache = new InMemoryLRUCache(),
keyValueCache: KeyValueCache = new InMemoryLRUCache<string, CO>(),
httpFetch: Fetcher = nodeFetch,
) {
this.keyValueCache = new PrefixingKeyValueCache(
Expand All @@ -57,12 +57,12 @@ export class HTTPCache {
cache?: {
cacheKey?: string;
cacheOptions?:
| CacheOptions
| CO
| ((
url: string,
response: FetcherResponse,
request: RequestOptions,
) => ValueOrPromise<CacheOptions | undefined>);
) => ValueOrPromise<CO | undefined>);
httpCacheSemanticsCachePolicyOptions?: HttpCacheSemanticsOptions;
},
): Promise<ResponseWithCacheWritePromise> {
Expand Down Expand Up @@ -189,12 +189,12 @@ export class HTTPCache {
policy: SneakyCachePolicy,
cacheKey: string,
cacheOptions?:
| CacheOptions
| CO
| ((
url: string,
response: FetcherResponse,
request: RequestOptions,
) => ValueOrPromise<CacheOptions | undefined>),
) => ValueOrPromise<CO | undefined>),
): Promise<ResponseWithCacheWritePromise> {
if (typeof cacheOptions === 'function') {
cacheOptions = await cacheOptions(url, response, request);
Expand Down Expand Up @@ -246,6 +246,7 @@ export class HTTPCache {
cacheWritePromise: this.readResponseAndWriteToCache({
response,
policy,
cacheOptions,
ttl,
ttlOverride,
cacheKey,
Expand All @@ -256,12 +257,14 @@ export class HTTPCache {
private async readResponseAndWriteToCache({
response,
policy,
cacheOptions,
ttl,
ttlOverride,
cacheKey,
}: {
response: FetcherResponse;
policy: CachePolicy;
cacheOptions?: CO;
ttl: number | null | undefined;
ttlOverride: number | undefined;
cacheKey: string;
Expand All @@ -273,9 +276,11 @@ export class HTTPCache {
body,
});

// Set the value into the cache, and forward all the set cache option into the setter function
await this.keyValueCache.set(cacheKey, entry, {
...cacheOptions,
ttl,
});
} as CO);
}
}

Expand Down
Loading

0 comments on commit 147f820

Please sign in to comment.