Skip to content

Commit cb6d72e

Browse files
authored
Disable memoization for specific requests (#26)
1 parent 5f0036f commit cb6d72e

File tree

2 files changed

+222
-47
lines changed

2 files changed

+222
-47
lines changed

src/http-data-source.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ export type Request<T = unknown> = {
4848
origin: string
4949
path: string
5050
method: HttpMethod
51+
// Indicates if the response of this request should be memoized
52+
memoize?: boolean
5153
headers: Dictionary<string>
5254
} & CacheTTLOptions
5355

@@ -87,7 +89,7 @@ export abstract class HTTPDataSource<TContext = any> extends DataSource {
8789
private logger?: Logger
8890
private cache!: KeyValueCache<string>
8991
private globalRequestOptions?: RequestOptions
90-
private readonly memoizedResults: QuickLRU<string, Promise<Response<any>>>
92+
private readonly memoizedResults: QuickLRU<string, Response<any>>
9193

9294
constructor(public readonly baseURL: string, private readonly options?: HTTPDataSourceOptions) {
9395
super()
@@ -141,6 +143,16 @@ export abstract class HTTPDataSource<TContext = any> extends DataSource {
141143
return statusCodeCacheableByDefault.has(response.statusCode) && request.method === 'GET'
142144
}
143145

146+
/**
147+
* Checks if the GET request is memoizable. This validation is performed before the
148+
* response is set in **memoizedResults**.
149+
* @param request
150+
* @returns *true* if request should be memoized
151+
*/
152+
protected isRequestMemoizable(request: Request): boolean {
153+
return Boolean(request.memoize) && request.method === 'GET'
154+
}
155+
144156
/**
145157
* onCacheKeyCalculation returns the key for the GET request.
146158
* The key is used to memoize the request in the LRU cache.
@@ -185,6 +197,14 @@ export abstract class HTTPDataSource<TContext = any> extends DataSource {
185197

186198
protected onError?(_error: Error, requestOptions: Request): void
187199

200+
/**
201+
* Execute a HTTP GET request.
202+
* Note that the **memoizedResults** and **cache** will be checked before request is made.
203+
* By default the received response will be memoized.
204+
*
205+
* @param path the path to the resource
206+
* @param requestOptions
207+
*/
188208
public async get<TResult = unknown>(
189209
path: string,
190210
requestOptions?: RequestOptions,
@@ -193,6 +213,7 @@ export abstract class HTTPDataSource<TContext = any> extends DataSource {
193213
headers: {},
194214
query: {},
195215
body: null,
216+
memoize: true,
196217
context: {},
197218
...requestOptions,
198219
method: 'GET',
@@ -312,6 +333,10 @@ export abstract class HTTPDataSource<TContext = any> extends DataSource {
312333

313334
this.onResponse<TResult>(request, response)
314335

336+
if (this.isRequestMemoizable(request)) {
337+
this.memoizedResults.set(cacheKey, response)
338+
}
339+
315340
// let's see if we can fill the shared cache
316341
if (request.requestCache && this.isResponseCacheable<TResult>(request, response)) {
317342
response.maxTtl = request.requestCache.maxTtl
@@ -390,15 +415,14 @@ export abstract class HTTPDataSource<TContext = any> extends DataSource {
390415
return cachedResponse
391416
}
392417
const response = this.performRequest<TResult>(options, cacheKey)
393-
this.memoizedResults.set(cacheKey, response)
418+
394419
return response
395420
} catch (error: any) {
396421
this.logger?.error(`Cache item '${cacheKey}' could not be loaded: ${error.message}`)
397422
}
398423
}
399424

400425
const response = this.performRequest<TResult>(options, cacheKey)
401-
this.memoizedResults.set(cacheKey, response)
402426

403427
return response
404428
}

0 commit comments

Comments
 (0)