StarpTech / apollo-datasource-http

Optimized JSON HTTP Data Source for Apollo Server
MIT License
73 stars 32 forks source link

[Proposal]: Support caching responses without JSON.stringify #35

Open toeste opened 2 years ago

toeste commented 2 years ago

By default, apollo-datasource-rest stringifies responses when setting cached values: https://github.com/StarpTech/apollo-datasource-http/blob/main/src/http-data-source.ts#L349. (Responses are not stringified when caching for memoization: https://github.com/StarpTech/apollo-datasource-http/blob/main/src/http-data-source.ts#L343.)

The underlying KeyValueCache from Apollo Server allows non-string types for the cached value: https://github.com/apollographql/apollo-server/blob/0aa0e4b20ef97576ce92733698a7842b61d8280e/packages/apollo-server-caching/src/KeyValueCache.ts#L10-L14.

Could an additional requestCache option (https://github.com/StarpTech/apollo-datasource-http/blob/main/src/http-data-source.ts#L28) be added to control whether or not responses are stringified and parsed when setting and getting from the cache? I have a use case where I am caching a lot of large responses, and the stringify and parse steps can add significant overhead at scale.

Simplified proposal

const cachedResponse = request.requestCache.stringifyResponse ? JSON.stringify(response) : response;
...
const response: Response<TResult> = request.requestCache.stringifyResponse ? JSON.parse(cacheItem) : cacheItem;
llc1123 commented 2 years ago

Actually, you can't.

export interface KeyValueCache<V = string> {
  get(key: string): Promise<V | undefined>;
  set(key: string, value: V, options?: KeyValueCacheSetOptions): Promise<void>;
  delete(key: string): Promise<boolean | void>;
}

export interface DataSourceConfig<TContext> {
  context: TContext;
  cache: KeyValueCache;
}

export abstract class DataSource<TContext = any> {
  initialize?(config: DataSourceConfig<TContext>): void | Promise<void>;
}

Apollo server initializes the data source with config: DataSourceConfig<TContext> which doesn't allow cache to be anything else than KeyValueCache<string>.