@apollo/gateway 2.0.1 → 2.0.2-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +2 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/datasources/RemoteGraphQLDataSource.d.ts +6 -5
- package/dist/datasources/RemoteGraphQLDataSource.d.ts.map +1 -1
- package/dist/datasources/RemoteGraphQLDataSource.js +18 -13
- package/dist/datasources/RemoteGraphQLDataSource.js.map +1 -1
- package/dist/executeQueryPlan.d.ts.map +1 -1
- package/dist/executeQueryPlan.js +2 -2
- package/dist/executeQueryPlan.js.map +1 -1
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -25
- package/dist/index.js.map +1 -1
- package/dist/schema-helper/addExtensions.d.ts +3 -0
- package/dist/schema-helper/addExtensions.d.ts.map +1 -0
- package/dist/schema-helper/addExtensions.js +20 -0
- package/dist/schema-helper/addExtensions.js.map +1 -0
- package/dist/supergraphManagers/UplinkFetcher/index.d.ts +2 -2
- package/dist/supergraphManagers/UplinkFetcher/index.d.ts.map +1 -1
- package/dist/supergraphManagers/UplinkFetcher/index.js.map +1 -1
- package/dist/supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.d.ts +3 -3
- package/dist/supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.d.ts.map +1 -1
- package/dist/supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.js +14 -13
- package/dist/supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.js.map +1 -1
- package/dist/supergraphManagers/UplinkFetcher/outOfBandReporter.d.ts +6 -5
- package/dist/supergraphManagers/UplinkFetcher/outOfBandReporter.d.ts.map +1 -1
- package/dist/supergraphManagers/UplinkFetcher/outOfBandReporter.js +3 -3
- package/dist/supergraphManagers/UplinkFetcher/outOfBandReporter.js.map +1 -1
- package/dist/typings/graphql.d.ts +34 -0
- package/dist/typings/graphql.d.ts.map +1 -0
- package/dist/{schema-helper/resolverMap.js → typings/graphql.js} +1 -1
- package/dist/typings/graphql.js.map +1 -0
- package/package.json +10 -8
- package/src/__tests__/executeQueryPlan.test.ts +4 -1
- package/src/__tests__/execution-utils.ts +2 -2
- package/src/__tests__/gateway/buildService.test.ts +81 -83
- package/src/__tests__/gateway/endToEnd.test.ts +1 -1
- package/src/__tests__/gateway/executor.test.ts +20 -17
- package/src/__tests__/gateway/extensions.test.ts +37 -0
- package/src/__tests__/gateway/lifecycle-hooks.test.ts +1 -1
- package/src/__tests__/gateway/opentelemetry.test.ts +3 -7
- package/src/__tests__/gateway/reporting.test.ts +1 -1
- package/src/__tests__/gateway/supergraphSdl.test.ts +7 -12
- package/src/config.ts +2 -2
- package/src/datasources/RemoteGraphQLDataSource.ts +34 -18
- package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +1 -1
- package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +106 -140
- package/src/executeQueryPlan.ts +5 -1
- package/src/index.ts +15 -32
- package/src/schema-helper/__tests__/addExtensions.test.ts +11 -0
- package/src/schema-helper/addExtensions.ts +17 -0
- package/src/supergraphManagers/IntrospectAndCompose/__tests__/IntrospectAndCompose.test.ts +0 -6
- package/src/supergraphManagers/UplinkFetcher/__tests__/loadSupergraphSdlFromStorage.test.ts +70 -74
- package/src/supergraphManagers/UplinkFetcher/index.ts +2 -2
- package/src/supergraphManagers/UplinkFetcher/loadSupergraphSdlFromStorage.ts +23 -17
- package/src/supergraphManagers/UplinkFetcher/outOfBandReporter.ts +9 -7
- package/src/typings/graphql.ts +43 -0
- package/dist/cache.d.ts +0 -18
- package/dist/cache.d.ts.map +0 -1
- package/dist/cache.js +0 -46
- package/dist/cache.js.map +0 -1
- package/dist/schema-helper/addResolversToSchema.d.ts +0 -4
- package/dist/schema-helper/addResolversToSchema.d.ts.map +0 -1
- package/dist/schema-helper/addResolversToSchema.js +0 -62
- package/dist/schema-helper/addResolversToSchema.js.map +0 -1
- package/dist/schema-helper/error.d.ts +0 -6
- package/dist/schema-helper/error.d.ts.map +0 -1
- package/dist/schema-helper/error.js +0 -14
- package/dist/schema-helper/error.js.map +0 -1
- package/dist/schema-helper/index.d.ts +0 -4
- package/dist/schema-helper/index.d.ts.map +0 -1
- package/dist/schema-helper/index.js +0 -20
- package/dist/schema-helper/index.js.map +0 -1
- package/dist/schema-helper/resolverMap.d.ts +0 -16
- package/dist/schema-helper/resolverMap.d.ts.map +0 -1
- package/dist/schema-helper/resolverMap.js.map +0 -1
- package/dist/utilities/createHash.d.ts +0 -2
- package/dist/utilities/createHash.d.ts.map +0 -1
- package/dist/utilities/createHash.js +0 -15
- package/dist/utilities/createHash.js.map +0 -1
- package/dist/utilities/isNodeLike.d.ts +0 -3
- package/dist/utilities/isNodeLike.d.ts.map +0 -1
- package/dist/utilities/isNodeLike.js +0 -8
- package/dist/utilities/isNodeLike.js.map +0 -1
- package/src/__mocks__/apollo-server-env.ts +0 -56
- package/src/__mocks__/make-fetch-happen-fetcher.ts +0 -57
- package/src/cache.ts +0 -66
- package/src/make-fetch-happen.d.ts +0 -59
- package/src/schema-helper/addResolversToSchema.ts +0 -83
- package/src/schema-helper/error.ts +0 -11
- package/src/schema-helper/index.ts +0 -3
- package/src/schema-helper/resolverMap.ts +0 -23
- package/src/utilities/createHash.ts +0 -10
- package/src/utilities/isNodeLike.ts +0 -11
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import gql from 'graphql-tag';
|
|
2
2
|
import {ApolloGateway, LocalGraphQLDataSource} from '../../';
|
|
3
3
|
import {fixtures, spanSerializer} from 'apollo-federation-integration-testsuite';
|
|
4
|
-
import {fetch} from '../../__mocks__/apollo-server-env';
|
|
5
4
|
import {InMemorySpanExporter, SimpleSpanProcessor} from '@opentelemetry/tracing'
|
|
6
5
|
import {NodeTracerProvider} from '@opentelemetry/node';
|
|
7
6
|
import { buildSubgraphSchema } from '@apollo/subgraph';
|
|
@@ -14,7 +13,6 @@ tracerProvider.addSpanProcessor(new SimpleSpanProcessor(inMemorySpans));
|
|
|
14
13
|
tracerProvider.register();
|
|
15
14
|
|
|
16
15
|
beforeEach(() => {
|
|
17
|
-
fetch.mockReset();
|
|
18
16
|
inMemorySpans.reset();
|
|
19
17
|
});
|
|
20
18
|
|
|
@@ -102,13 +100,11 @@ describe('opentelemetry', () => {
|
|
|
102
100
|
|
|
103
101
|
|
|
104
102
|
it('receives spans on fetch failure', async () => {
|
|
105
|
-
|
|
106
|
-
fetch.mockImplementationOnce(async () => {
|
|
107
|
-
throw Error("Nooo");
|
|
108
|
-
});
|
|
109
|
-
|
|
110
103
|
const gateway = new ApolloGateway({
|
|
111
104
|
localServiceList: fixtures,
|
|
105
|
+
fetcher: () => {
|
|
106
|
+
throw Error('Nooo');
|
|
107
|
+
},
|
|
112
108
|
});
|
|
113
109
|
|
|
114
110
|
const { executor } = await gateway.load();
|
|
@@ -13,7 +13,7 @@ import { Plugin, Config, Refs } from 'pretty-format';
|
|
|
13
13
|
import { Report, Trace } from 'apollo-reporting-protobuf';
|
|
14
14
|
import { fixtures } from 'apollo-federation-integration-testsuite';
|
|
15
15
|
import { nockAfterEach, nockBeforeEach } from '../nockAssertions';
|
|
16
|
-
import { GraphQLSchemaModule } from '
|
|
16
|
+
import { GraphQLSchemaModule } from '@apollo/subgraph/src/schema-helper';
|
|
17
17
|
import resolvable, { Resolvable } from '@josephg/resolvable';
|
|
18
18
|
|
|
19
19
|
// Normalize specific fields that change often (eg timestamps) to static values,
|
|
@@ -4,15 +4,15 @@ import {
|
|
|
4
4
|
SubgraphHealthCheckFunction,
|
|
5
5
|
SupergraphSdlUpdateFunction,
|
|
6
6
|
} from '@apollo/gateway';
|
|
7
|
-
import { fixturesWithUpdate } from 'apollo-federation-integration-testsuite';
|
|
8
|
-
import { createHash } from '
|
|
7
|
+
import { accounts, fixturesWithUpdate } from 'apollo-federation-integration-testsuite';
|
|
8
|
+
import { createHash } from '@apollo/utils.createhash';
|
|
9
9
|
import { ApolloServer } from 'apollo-server';
|
|
10
10
|
import type { Logger } from '@apollo/utils.logger';
|
|
11
|
-
import { fetch } from '../../__mocks__/make-fetch-happen-fetcher';
|
|
12
11
|
import { getTestingSupergraphSdl } from '../execution-utils';
|
|
13
12
|
import { mockAllServicesHealthCheckSuccess } from '../integration/nockMocks';
|
|
14
13
|
import resolvable from '@josephg/resolvable';
|
|
15
14
|
import { nockAfterEach, nockBeforeEach } from '../nockAssertions';
|
|
15
|
+
import nock from 'nock';
|
|
16
16
|
|
|
17
17
|
async function getSupergraphSdlGatewayServer() {
|
|
18
18
|
const server = new ApolloServer({
|
|
@@ -21,7 +21,6 @@ async function getSupergraphSdlGatewayServer() {
|
|
|
21
21
|
buildService({ url }) {
|
|
22
22
|
return new RemoteGraphQLDataSource({
|
|
23
23
|
url,
|
|
24
|
-
fetcher: fetch,
|
|
25
24
|
});
|
|
26
25
|
},
|
|
27
26
|
}),
|
|
@@ -59,9 +58,10 @@ describe('Using supergraphSdl static configuration', () => {
|
|
|
59
58
|
it('successfully starts and serves requests to the proper services', async () => {
|
|
60
59
|
const server = await getSupergraphSdlGatewayServer();
|
|
61
60
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
nock(accounts.url)
|
|
62
|
+
.post('/', { query: '{me{username}}', variables: {} })
|
|
63
|
+
.reply(200, { data: { me: { username: '@jbaxleyiii' } } });
|
|
64
|
+
|
|
65
65
|
|
|
66
66
|
const result = await server.executeOperation({
|
|
67
67
|
query: '{ me { username } }',
|
|
@@ -75,11 +75,6 @@ describe('Using supergraphSdl static configuration', () => {
|
|
|
75
75
|
}
|
|
76
76
|
`);
|
|
77
77
|
|
|
78
|
-
const [url, request] = fetch.mock.calls[0];
|
|
79
|
-
expect(url).toEqual('https://accounts.api.com.invalid');
|
|
80
|
-
expect(request?.body).toEqual(
|
|
81
|
-
JSON.stringify({ query: '{me{username}}', variables: {} }),
|
|
82
|
-
);
|
|
83
78
|
await server.stop();
|
|
84
79
|
});
|
|
85
80
|
});
|
package/src/config.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { GraphQLError, GraphQLSchema } from 'graphql';
|
|
2
2
|
import { HeadersInit } from 'node-fetch';
|
|
3
|
-
import { fetch } from 'apollo-server-env';
|
|
4
3
|
import { GraphQLRequestContextExecutionDidStart } from 'apollo-server-types';
|
|
5
4
|
import type { Logger } from '@apollo/utils.logger';
|
|
6
5
|
import { GraphQLDataSource } from './datasources/types';
|
|
@@ -8,6 +7,7 @@ import { QueryPlan } from '@apollo/query-planner';
|
|
|
8
7
|
import { OperationContext } from './operationContext';
|
|
9
8
|
import { ServiceMap } from './executeQueryPlan';
|
|
10
9
|
import { ServiceDefinition } from "@apollo/federation-internals";
|
|
10
|
+
import { Fetcher } from '@apollo/utils.fetcher';
|
|
11
11
|
|
|
12
12
|
export type ServiceEndpointDefinition = Pick<ServiceDefinition, 'name' | 'url'>;
|
|
13
13
|
|
|
@@ -126,7 +126,7 @@ interface GatewayConfigBase {
|
|
|
126
126
|
experimental_didUpdateSupergraph?: Experimental_DidUpdateSupergraphCallback;
|
|
127
127
|
experimental_approximateQueryPlanStoreMiB?: number;
|
|
128
128
|
experimental_autoFragmentization?: boolean;
|
|
129
|
-
fetcher?:
|
|
129
|
+
fetcher?: Fetcher;
|
|
130
130
|
serviceHealthCheck?: boolean;
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -12,17 +12,19 @@ import {
|
|
|
12
12
|
AuthenticationError,
|
|
13
13
|
ForbiddenError,
|
|
14
14
|
} from 'apollo-server-errors';
|
|
15
|
-
import { fetch, Request, Headers, Response } from 'apollo-server-env';
|
|
16
15
|
import { isObject } from '../utilities/predicates';
|
|
17
16
|
import { GraphQLDataSource, GraphQLDataSourceProcessOptions, GraphQLDataSourceRequestKind } from './types';
|
|
18
|
-
import
|
|
17
|
+
import { createHash } from '@apollo/utils.createhash';
|
|
19
18
|
import { parseCacheControlHeader } from './parseCacheControlHeader';
|
|
20
19
|
import fetcher from 'make-fetch-happen';
|
|
20
|
+
import { Headers as NodeFetchHeaders, Request as NodeFetchRequest } from 'node-fetch';
|
|
21
|
+
import { Fetcher, FetcherRequestInit, FetcherResponse } from '@apollo/utils.fetcher';
|
|
22
|
+
|
|
21
23
|
export class RemoteGraphQLDataSource<
|
|
22
24
|
TContext extends Record<string, any> = Record<string, any>,
|
|
23
25
|
> implements GraphQLDataSource<TContext>
|
|
24
26
|
{
|
|
25
|
-
fetcher:
|
|
27
|
+
fetcher: Fetcher;
|
|
26
28
|
|
|
27
29
|
constructor(
|
|
28
30
|
config?: Partial<RemoteGraphQLDataSource<TContext>> &
|
|
@@ -30,6 +32,11 @@ export class RemoteGraphQLDataSource<
|
|
|
30
32
|
ThisType<RemoteGraphQLDataSource<TContext>>,
|
|
31
33
|
) {
|
|
32
34
|
this.fetcher = fetcher.defaults({
|
|
35
|
+
// Allow an arbitrary number of sockets per subgraph. This is the default
|
|
36
|
+
// behavior of Node's http.Agent as well as the npm package agentkeepalive
|
|
37
|
+
// which wraps it, but is not the default behavior of make-fetch-happen
|
|
38
|
+
// which wraps agentkeepalive (that package sets this to 15 by default).
|
|
39
|
+
maxSockets: Infinity,
|
|
33
40
|
// although this is the default, we want to take extra care and be very
|
|
34
41
|
// explicity to ensure that mutations cannot be retried. please leave this
|
|
35
42
|
// intact.
|
|
@@ -82,7 +89,12 @@ export class RemoteGraphQLDataSource<
|
|
|
82
89
|
const context = originalContext as TContext;
|
|
83
90
|
|
|
84
91
|
// Respect incoming http headers (eg, apollo-federation-include-trace).
|
|
85
|
-
const headers =
|
|
92
|
+
const headers = new NodeFetchHeaders();
|
|
93
|
+
if (request.http?.headers) {
|
|
94
|
+
for (const [name, value] of request.http.headers) {
|
|
95
|
+
headers.append(name, value);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
86
98
|
headers.set('Content-Type', 'application/json');
|
|
87
99
|
|
|
88
100
|
request.http = {
|
|
@@ -112,7 +124,7 @@ export class RemoteGraphQLDataSource<
|
|
|
112
124
|
: null;
|
|
113
125
|
|
|
114
126
|
if (this.apq) {
|
|
115
|
-
const apqHash =
|
|
127
|
+
const apqHash = createHash('sha256').update(request.query).digest('hex');
|
|
116
128
|
|
|
117
129
|
// Take the original extensions and extend them with
|
|
118
130
|
// the necessary "extensions" for APQ handshaking.
|
|
@@ -177,20 +189,24 @@ export class RemoteGraphQLDataSource<
|
|
|
177
189
|
// we're accessing (e.g. url) and what we access it with (e.g. headers).
|
|
178
190
|
const { http, ...requestWithoutHttp } = request;
|
|
179
191
|
const stringifiedRequestWithoutHttp = JSON.stringify(requestWithoutHttp);
|
|
180
|
-
const
|
|
181
|
-
|
|
192
|
+
const requestInit: FetcherRequestInit = {
|
|
193
|
+
method: http.method,
|
|
194
|
+
headers: Object.fromEntries(http.headers),
|
|
182
195
|
body: stringifiedRequestWithoutHttp,
|
|
183
|
-
}
|
|
196
|
+
};
|
|
197
|
+
// Note that we don't actually send this Request object to the fetcher; it
|
|
198
|
+
// is merely sent to methods on this object that might be overridden by users.
|
|
199
|
+
// We are careful to only send data to the overridable fetcher function that uses
|
|
200
|
+
// plain JS objects --- some fetch implementations don't know how to handle
|
|
201
|
+
// Request or Headers objects created by other fetch implementations.
|
|
202
|
+
const fetchRequest = new NodeFetchRequest(http.url, requestInit);
|
|
184
203
|
|
|
185
|
-
let fetchResponse:
|
|
204
|
+
let fetchResponse: FetcherResponse | undefined;
|
|
186
205
|
|
|
187
206
|
try {
|
|
188
207
|
// Use our local `fetcher` to allow for fetch injection
|
|
189
208
|
// Use the fetcher's `Request` implementation for compatibility
|
|
190
|
-
fetchResponse = await this.fetcher(http.url,
|
|
191
|
-
...http,
|
|
192
|
-
body: stringifiedRequestWithoutHttp,
|
|
193
|
-
});
|
|
209
|
+
fetchResponse = await this.fetcher(http.url, requestInit);
|
|
194
210
|
|
|
195
211
|
if (!fetchResponse.ok) {
|
|
196
212
|
throw await this.errorFromResponse(fetchResponse);
|
|
@@ -266,16 +282,16 @@ export class RemoteGraphQLDataSource<
|
|
|
266
282
|
|
|
267
283
|
public didEncounterError(
|
|
268
284
|
error: Error,
|
|
269
|
-
_fetchRequest:
|
|
270
|
-
_fetchResponse?:
|
|
285
|
+
_fetchRequest: NodeFetchRequest,
|
|
286
|
+
_fetchResponse?: FetcherResponse,
|
|
271
287
|
_context?: TContext,
|
|
272
288
|
) {
|
|
273
289
|
throw error;
|
|
274
290
|
}
|
|
275
291
|
|
|
276
292
|
public parseBody(
|
|
277
|
-
fetchResponse:
|
|
278
|
-
_fetchRequest?:
|
|
293
|
+
fetchResponse: FetcherResponse,
|
|
294
|
+
_fetchRequest?: NodeFetchRequest,
|
|
279
295
|
_context?: TContext,
|
|
280
296
|
): Promise<object | string> {
|
|
281
297
|
const contentType = fetchResponse.headers.get('Content-Type');
|
|
@@ -286,7 +302,7 @@ export class RemoteGraphQLDataSource<
|
|
|
286
302
|
}
|
|
287
303
|
}
|
|
288
304
|
|
|
289
|
-
public async errorFromResponse(response:
|
|
305
|
+
public async errorFromResponse(response: FetcherResponse) {
|
|
290
306
|
const message = `${response.status}: ${response.statusText}`;
|
|
291
307
|
|
|
292
308
|
let error: ApolloError;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LocalGraphQLDataSource } from '../LocalGraphQLDataSource';
|
|
2
2
|
import { buildSubgraphSchema } from '@apollo/subgraph';
|
|
3
3
|
import gql from 'graphql-tag';
|
|
4
|
-
import { GraphQLResolverMap } from '
|
|
4
|
+
import { GraphQLResolverMap } from '@apollo/subgraph/src/schema-helper';
|
|
5
5
|
import { GraphQLRequestContext } from 'apollo-server-types';
|
|
6
6
|
import { GraphQLDataSourceRequestKind } from '../types';
|
|
7
7
|
|