diff --git a/.changeset/tiny-queens-attend.md b/.changeset/tiny-queens-attend.md new file mode 100644 index 0000000..a4d47d5 --- /dev/null +++ b/.changeset/tiny-queens-attend.md @@ -0,0 +1,5 @@ +--- +"@apollo/datasource-rest": minor +--- + +Allow cache to be skipped on RestDataSource HTTP requests diff --git a/src/HTTPCache.ts b/src/HTTPCache.ts index 0f65f51..fda4a56 100644 --- a/src/HTTPCache.ts +++ b/src/HTTPCache.ts @@ -75,7 +75,10 @@ export class HTTPCache { return { response: await this.httpFetch(urlString, requestOpts) }; } - const entry = await this.keyValueCache.get(cacheKey); + const entry = + requestOpts.skipCache !== true + ? await this.keyValueCache.get(cacheKey) + : undefined; if (!entry) { // There's nothing in our cache. Fetch the URL and save it to the cache if // we're allowed. diff --git a/src/RESTDataSource.ts b/src/RESTDataSource.ts index 7f44790..e87a619 100644 --- a/src/RESTDataSource.ts +++ b/src/RESTDataSource.ts @@ -45,6 +45,11 @@ export type RequestOptions = response: FetcherResponse, request: RequestOptions, ) => ValueOrPromise); + /** + * Do not check the cache ignoring TTL or other cache settings + * Useful when you suspect a value may be cached but you want to force fresh data + */ + skipCache?: boolean; /** * If provided, this is passed through as the third argument to `new * CachePolicy()` from the `http-cache-semantics` npm package as part of the diff --git a/src/__tests__/HTTPCache.test.ts b/src/__tests__/HTTPCache.test.ts index 91a38f1..0f6b255 100644 --- a/src/__tests__/HTTPCache.test.ts +++ b/src/__tests__/HTTPCache.test.ts @@ -130,6 +130,36 @@ describe('HTTPCache', () => { expect(response.headers.get('age')).toEqual('10'); }); + it('fetches fresh response when TTL not expired but skipCache true', async () => { + mockGetAdaLovelace({ + 'cache-control': 'private, no-cache', + 'set-cookie': 'foo', + }); + + const { cacheWritePromise } = await httpCache.fetch( + adaUrl, + {}, + { + cacheOptions: { + ttl: 30, + }, + }, + ); + + await cacheWritePromise; + jest.advanceTimersByTime(10000); + + mockGetAlanTuring({ + 'cache-control': 'private, no-cache', + 'set-cookie': 'foo', + }); + + const { response } = await httpCache.fetch(adaUrl, { skipCache: true }); + + expect(await response.json()).toEqual({ name: 'Alan Turing' }); + expect(response.headers.get('age')).toBeNull(); + }); + it('fetches a fresh response from the origin when the overridden TTL expired', async () => { mockGetAdaLovelace({ 'cache-control': 'private, no-cache',