Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it possible to pass custom fetch to rest data source #1807

Merged
merged 4 commits into from
Jul 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ the query extensions' `clientInfo` values will be used. [PR #1960](https://githu
- Azure functions support [Issue #1752](https://github.com/apollographql/apollo-server/issue/1752) [PR #1753](https://github.com/apollographql/apollo-server/pull/1753) [PR #1948](https://github.com/apollographql/apollo-server/pull/1948)
- Allow JSON parsing in `RESTDataSource` of Content Type `application/hal+json`. [PR #185](https://github.com/apollographql/apollo-server/pull/1853)
- Add support for a `requestAgent` configuration parameter within the `engine` configuration. This can be utilized when a proxy is necessary to transmit tracing and metrics data to Apollo Engine. It accepts either an [`http.Agent`](https://nodejs.org/docs/latest-v8.x/api/http.html#http_class_http_agent) or [`https.Agent`](https://nodejs.org/docs/latest-v8.x/api/https.html#https_class_https_agent) and behaves the same as the `agent` parameter to Node.js' [`http.request`](https://nodejs.org/docs/latest-v8.x/api/http.html#http_http_request_options_callback). [PR #1879](https://github.com/apollographql/apollo-server/pull/1879)
- Allow an optional parameter to the `RESTDataSource` constructor which takes a `node-fetch`-compatible `fetch` implementation that will be used for HTTP calls instead of the default fetch. [PR #1807](https://github.com/apollographql/apollo-server/pull/1807)

### v2.1.0

Expand Down
12 changes: 9 additions & 3 deletions packages/apollo-datasource-rest/src/HTTPCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ import { CacheOptions } from './RESTDataSource';

export class HTTPCache {
private keyValueCache: KeyValueCache;
constructor(keyValueCache: KeyValueCache = new InMemoryLRUCache()) {
private httpFetch: typeof fetch;

constructor(
keyValueCache: KeyValueCache = new InMemoryLRUCache(),
httpFetch: typeof fetch = fetch,
) {
this.keyValueCache = new PrefixingKeyValueCache(
keyValueCache,
'httpcache:',
);
this.httpFetch = httpFetch;
}

async fetch(
Expand All @@ -31,7 +37,7 @@ export class HTTPCache {

const entry = await this.keyValueCache.get(cacheKey);
if (!entry) {
const response = await fetch(request);
const response = await this.httpFetch(request);

const policy = new CachePolicy(
policyRequestFrom(request),
Expand Down Expand Up @@ -71,7 +77,7 @@ export class HTTPCache {
const revalidationRequest = new Request(request, {
headers: revalidationHeaders,
});
const revalidationResponse = await fetch(revalidationRequest);
const revalidationResponse = await this.httpFetch(revalidationRequest);

const { policy: revalidatedPolicy, modified } = policy.revalidatedPolicy(
policyRequestFrom(revalidationRequest),
Expand Down
7 changes: 6 additions & 1 deletion packages/apollo-datasource-rest/src/RESTDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
URL,
URLSearchParams,
URLSearchParamsInit,
fetch,
ValueOrPromise,
} from 'apollo-server-env';

Expand Down Expand Up @@ -47,9 +48,13 @@ export abstract class RESTDataSource<TContext = any> extends DataSource {
context!: TContext;
memoizedResults = new Map<string, Promise<any>>();

constructor(private httpFetch?: typeof fetch) {
super();
}

initialize(config: DataSourceConfig<TContext>): void {
this.context = config.context;
this.httpCache = new HTTPCache(config.cache);
this.httpCache = new HTTPCache(config.cache, this.httpFetch);
}

baseURL?: string;
Expand Down
14 changes: 14 additions & 0 deletions packages/apollo-datasource-rest/src/__tests__/HTTPCache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,4 +459,18 @@ describe('HTTPCache', () => {
expect(await response2.json()).toEqual({ name: 'Alan Turing' });
expect(response2.headers.get('Age')).toEqual('10');
});

it('fetches a response from the origin with a custom fetch function', async () => {
fetch.mockJSONResponseOnce({ name: 'Ada Lovelace' });

const customFetch = jest.fn(fetch);
const customHttpCache = new HTTPCache(store as any, customFetch);

const response = await customHttpCache.fetch(
new Request('https://api.example.com/people/1'),
);

expect(customFetch.mock.calls.length).toEqual(1);
expect(await response.json()).toEqual({ name: 'Ada Lovelace' });
});
});