diff --git a/federation-js/CHANGELOG.md b/federation-js/CHANGELOG.md index de1b2d3c5d..a0dc25f3ae 100644 --- a/federation-js/CHANGELOG.md +++ b/federation-js/CHANGELOG.md @@ -6,6 +6,10 @@ - _Nothing yet! Stay tuned._ +## 0.16.1 + +- Only changes in the similarly versioned `@apollo/gateway` package. + ## 0.16.0 - No changes. This package was major versioned to maintain lockstep versioning with @apollo/gateway. diff --git a/federation-js/package.json b/federation-js/package.json index 4017608c05..f978561161 100644 --- a/federation-js/package.json +++ b/federation-js/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/federation", - "version": "0.16.0", + "version": "0.16.1", "description": "Apollo Federation Utilities", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/gateway-js/CHANGELOG.md b/gateway-js/CHANGELOG.md index 079a262ce6..e2d799a7bf 100644 --- a/gateway-js/CHANGELOG.md +++ b/gateway-js/CHANGELOG.md @@ -6,6 +6,13 @@ - __FIX__: Collapse nested required fields into a single body in the query plan. Before, some nested fields' selection sets were getting split, causing some of their subfields to be dropped when executing the query. This fix collapses the split selection sets into one. [#4064](https://github.com/apollographql/apollo-server/pull/4064) +## 0.16.1 + +- __NEW__: Provide the ability to pass a custom `fetcher` during `RemoteGraphQLDataSource` construction to be used when executing operations against downstream services. Providing a custom `fetcher` may be necessary to accommodate more advanced needs, e.g., configuring custom TLS certificates for internal services. [PR #4149](https://github.com/apollographql/apollo-server/pull/4149) + + The `fetcher` specified should be a compliant implementor of the [Fetch API standard](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). This addition compliments, though is still orthognonal to, similar behavior originally introduced in [#3783](https://github.com/apollographql/apollo-server/pull/3783), which allowed customization of the implementation used to fetch _gateway configuration and federated SDL from services_ in managed and unmanaged modes, but didn't affect the communication that takes place during _operation execution_. + + For now, the default `fetcher` will remain the same ([`node-fetch`](https://npm.im/node-fetch)) implementation. A future major-version bump will update it to be consistent with other feature-rich implementations of the Fetch API which are used elsewhere in the Apollo Server stack where we use [`make-fetch-happen`](https://npm.im/make-fetch-happen). In all likelihood, `ApolloGateway` will pass its own `fetcher` to the `RemoteGraphQLDataSource` during service initialization. ## 0.16.0 diff --git a/gateway-js/package.json b/gateway-js/package.json index da61a3b74c..ffa8c1c9b7 100644 --- a/gateway-js/package.json +++ b/gateway-js/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/gateway", - "version": "0.16.0", + "version": "0.16.1", "description": "Apollo Gateway", "author": "opensource@apollographql.com", "main": "dist/index.js", diff --git a/gateway-js/src/datasources/RemoteGraphQLDataSource.ts b/gateway-js/src/datasources/RemoteGraphQLDataSource.ts index feffde81b2..700e78e2f4 100644 --- a/gateway-js/src/datasources/RemoteGraphQLDataSource.ts +++ b/gateway-js/src/datasources/RemoteGraphQLDataSource.ts @@ -20,6 +20,8 @@ import { GraphQLDataSource } from './types'; import createSHA from 'apollo-server-core/dist/utils/createSHA'; export class RemoteGraphQLDataSource = Record> implements GraphQLDataSource { + fetcher: typeof fetch = fetch; + constructor( config?: Partial> & object & @@ -144,7 +146,8 @@ export class RemoteGraphQLDataSource = Reco }); try { - const httpResponse = await fetch(httpRequest); + // Use our local `fetcher` to allow for fetch injection + const httpResponse = await this.fetcher(httpRequest); if (!httpResponse.ok) { throw await this.errorFromResponse(httpResponse); diff --git a/gateway-js/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts b/gateway-js/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts index ff5309dc00..f81b39afb1 100644 --- a/gateway-js/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +++ b/gateway-js/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts @@ -9,6 +9,7 @@ import { import { RemoteGraphQLDataSource } from '../RemoteGraphQLDataSource'; import { Headers } from 'apollo-server-env'; import { GraphQLRequestContext } from 'apollo-server-types'; +import { Response } from '../../../../../../apollo-tooling/packages/apollo-env/lib'; beforeEach(() => { fetch.mockReset(); @@ -238,6 +239,29 @@ describe('constructing requests', () => { }); }); +describe('fetcher', () => { + it('uses a custom provided `fetcher`', async () => { + const injectedFetch = fetch.mockJSONResponseOnce({ data: { injected: true } }); + const DataSource = new RemoteGraphQLDataSource({ + url: 'https://api.example.com/foo', + fetcher: injectedFetch, + }); + + const { data } = await DataSource.process({ + request: { + query: '{ me { name } }', + variables: { id: '1' }, + }, + context: {}, + }); + + expect(injectedFetch).toHaveBeenCalled(); + expect(data).toEqual({injected: true}); + + }); + +}); + describe('willSendRequest', () => { it('allows for modifying variables', async () => { const DataSource = new RemoteGraphQLDataSource({ diff --git a/gateway-js/src/executeQueryPlan.ts b/gateway-js/src/executeQueryPlan.ts index 902c655290..b92aec7d61 100644 --- a/gateway-js/src/executeQueryPlan.ts +++ b/gateway-js/src/executeQueryPlan.ts @@ -89,11 +89,9 @@ export async function executeQueryPlan( }, rootValue: data, variableValues: requestContext.request.variables, - // FIXME: GraphQL extensions currently wraps every field and creates - // a field resolver. Because of this, when using with ApolloServer - // the defaultFieldResolver isn't called. We keep this here - // because it is the correct solution and when ApolloServer removes - // GraphQLExtensions this will be how alias support is maintained + // We have a special field resolver which ensures we support aliases. + // FIXME: It's _possible_ this will change after `graphql-extensions` is + // deprecated, though not certain. See here, also: https://git.io/Jf8cS. fieldResolver: defaultFieldResolverWithAliasSupport, })); } catch (error) { diff --git a/gateway-js/src/index.ts b/gateway-js/src/index.ts index 1daf6097d6..d74269f029 100644 --- a/gateway-js/src/index.ts +++ b/gateway-js/src/index.ts @@ -476,6 +476,10 @@ export class ApolloGateway implements GraphQLService { this.logger.debug('Schema loaded and ready for execution'); + // FIXME: The comment below may change when `graphql-extensions` is + // removed, as it will be soon. It's not clear if this will be temporary, + // as is suggested, after that time, because we still very much need to + // do this special alias resolving. Original comment: // this is a temporary workaround for GraphQLFieldExtensions automatic // wrapping of all fields when using ApolloServer. Here we wrap all fields // with support for resolving aliases as part of the root value which