@apollo/gateway 2.4.5 → 2.4.6
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/__generated__/graphqlTypes.d.ts +19 -1
- package/dist/__generated__/graphqlTypes.d.ts.map +1 -1
- package/dist/__generated__/graphqlTypes.js +1 -0
- package/dist/__generated__/graphqlTypes.js.map +1 -1
- package/package.json +4 -4
- package/src/__generated__/graphqlTypes.ts +33 -2
- package/src/__mocks__/tsconfig.json +0 -7
- package/src/__tests__/.gitkeep +0 -0
- package/src/__tests__/CucumberREADME.md +0 -96
- package/src/__tests__/build-query-plan.feature +0 -1471
- package/src/__tests__/buildQueryPlan.test.ts +0 -1225
- package/src/__tests__/executeQueryPlan.conditions.test.ts +0 -1488
- package/src/__tests__/executeQueryPlan.introspection.test.ts +0 -140
- package/src/__tests__/executeQueryPlan.test.ts +0 -6140
- package/src/__tests__/execution-utils.ts +0 -124
- package/src/__tests__/gateway/__snapshots__/opentelemetry.test.ts.snap +0 -195
- package/src/__tests__/gateway/buildService.test.ts +0 -249
- package/src/__tests__/gateway/endToEnd.test.ts +0 -486
- package/src/__tests__/gateway/executor.test.ts +0 -96
- package/src/__tests__/gateway/extensions.test.ts +0 -37
- package/src/__tests__/gateway/lifecycle-hooks.test.ts +0 -239
- package/src/__tests__/gateway/opentelemetry.test.ts +0 -123
- package/src/__tests__/gateway/queryPlanCache.test.ts +0 -231
- package/src/__tests__/gateway/queryPlannerConfig.test.ts +0 -101
- package/src/__tests__/gateway/reporting.test.ts +0 -616
- package/src/__tests__/gateway/supergraphSdl.test.ts +0 -396
- package/src/__tests__/gateway/testUtils.ts +0 -89
- package/src/__tests__/integration/abstract-types.test.ts +0 -1861
- package/src/__tests__/integration/aliases.test.ts +0 -180
- package/src/__tests__/integration/boolean.test.ts +0 -279
- package/src/__tests__/integration/complex-key.test.ts +0 -197
- package/src/__tests__/integration/configuration.test.ts +0 -404
- package/src/__tests__/integration/custom-directives.test.ts +0 -174
- package/src/__tests__/integration/execution-style.test.ts +0 -35
- package/src/__tests__/integration/fragments.test.ts +0 -237
- package/src/__tests__/integration/list-key.test.ts +0 -128
- package/src/__tests__/integration/logger.test.ts +0 -122
- package/src/__tests__/integration/managed.test.ts +0 -319
- package/src/__tests__/integration/merge-arrays.test.ts +0 -34
- package/src/__tests__/integration/multiple-key.test.ts +0 -327
- package/src/__tests__/integration/mutations.test.ts +0 -287
- package/src/__tests__/integration/networkRequests.test.ts +0 -542
- package/src/__tests__/integration/nockMocks.ts +0 -157
- package/src/__tests__/integration/provides.test.ts +0 -77
- package/src/__tests__/integration/requires.test.ts +0 -359
- package/src/__tests__/integration/scope.test.ts +0 -557
- package/src/__tests__/integration/single-service.test.ts +0 -119
- package/src/__tests__/integration/unions.test.ts +0 -79
- package/src/__tests__/integration/value-types.test.ts +0 -382
- package/src/__tests__/integration/variables.test.ts +0 -120
- package/src/__tests__/nockAssertions.ts +0 -20
- package/src/__tests__/queryPlanCucumber.test.ts +0 -55
- package/src/__tests__/resultShaping.test.ts +0 -605
- package/src/__tests__/testSetup.ts +0 -1
- package/src/__tests__/tsconfig.json +0 -8
- package/src/core/__tests__/core.test.ts +0 -412
- package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +0 -51
- package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +0 -574
- package/src/schema-helper/__tests__/addExtensions.test.ts +0 -70
- package/src/supergraphManagers/IntrospectAndCompose/__tests__/IntrospectAndCompose.test.ts +0 -364
- package/src/supergraphManagers/IntrospectAndCompose/__tests__/loadServicesFromRemoteEndpoint.test.ts +0 -40
- package/src/supergraphManagers/UplinkSupergraphManager/__tests__/UplinkSupergraphManager.test.ts +0 -65
- package/src/supergraphManagers/UplinkSupergraphManager/__tests__/loadSupergraphSdlFromStorage.test.ts +0 -511
- package/src/utilities/__tests__/deepMerge.test.ts +0 -77
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
GraphQLSchemaModule,
|
|
3
|
-
GraphQLResolverMap,
|
|
4
|
-
GraphQLSchemaValidationError,
|
|
5
|
-
} from '@apollo/subgraph/src/schema-helper';
|
|
6
|
-
import type { Logger } from '@apollo/utils.logger';
|
|
7
|
-
import { buildSubgraphSchema } from '@apollo/subgraph';
|
|
8
|
-
import {
|
|
9
|
-
executeQueryPlan,
|
|
10
|
-
buildOperationContext,
|
|
11
|
-
} from '@apollo/gateway';
|
|
12
|
-
import { QueryPlan, QueryPlanner } from '@apollo/query-planner';
|
|
13
|
-
import { LocalGraphQLDataSource } from '../datasources/LocalGraphQLDataSource';
|
|
14
|
-
import { mergeDeep } from '@apollo/client/utilities';
|
|
15
|
-
|
|
16
|
-
import { queryPlanSerializer, astSerializer } from 'apollo-federation-integration-testsuite';
|
|
17
|
-
import gql from 'graphql-tag';
|
|
18
|
-
import { fixtures } from 'apollo-federation-integration-testsuite';
|
|
19
|
-
import { composeServices } from '@apollo/composition';
|
|
20
|
-
import { buildSchema, Operation, operationFromDocument, ServiceDefinition } from '@apollo/federation-internals';
|
|
21
|
-
import { GatewayExecutionResult, GatewayGraphQLRequest } from '@apollo/server-gateway-interface';
|
|
22
|
-
|
|
23
|
-
const prettyFormat = require('pretty-format');
|
|
24
|
-
|
|
25
|
-
export type ServiceDefinitionModule = ServiceDefinition & GraphQLSchemaModule;
|
|
26
|
-
|
|
27
|
-
export function overrideResolversInService(
|
|
28
|
-
module: ServiceDefinitionModule,
|
|
29
|
-
resolvers: GraphQLResolverMap,
|
|
30
|
-
): ServiceDefinitionModule {
|
|
31
|
-
return {
|
|
32
|
-
name: module.name,
|
|
33
|
-
typeDefs: module.typeDefs,
|
|
34
|
-
resolvers: mergeDeep(module.resolvers, resolvers),
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export async function execute(
|
|
39
|
-
request: GatewayGraphQLRequest,
|
|
40
|
-
services: ServiceDefinitionModule[] = fixtures,
|
|
41
|
-
logger: Logger = console,
|
|
42
|
-
): Promise<GatewayExecutionResult & { queryPlan: QueryPlan, operation: Operation }> {
|
|
43
|
-
const serviceMap = Object.fromEntries(
|
|
44
|
-
services.map(({ name, typeDefs, resolvers }) => {
|
|
45
|
-
return [
|
|
46
|
-
name,
|
|
47
|
-
new LocalGraphQLDataSource(
|
|
48
|
-
buildSubgraphSchema([{ typeDefs, resolvers }]),
|
|
49
|
-
),
|
|
50
|
-
] as [string, LocalGraphQLDataSource];
|
|
51
|
-
}),
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
const { schema, queryPlanner } = getFederatedTestingSchema(services);
|
|
55
|
-
|
|
56
|
-
const apiSchema = schema.toAPISchema();
|
|
57
|
-
const operationDocument = gql`${request.query}`;
|
|
58
|
-
const operation = operationFromDocument(apiSchema, operationDocument);
|
|
59
|
-
const queryPlan = queryPlanner.buildQueryPlan(operation);
|
|
60
|
-
|
|
61
|
-
const operationContext = buildOperationContext({
|
|
62
|
-
schema: apiSchema.toGraphQLJSSchema(),
|
|
63
|
-
operationDocument,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const result = await executeQueryPlan(
|
|
67
|
-
queryPlan,
|
|
68
|
-
serviceMap,
|
|
69
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
70
|
-
// @ts-ignore
|
|
71
|
-
{
|
|
72
|
-
cache: undefined as any,
|
|
73
|
-
context: {},
|
|
74
|
-
request,
|
|
75
|
-
logger
|
|
76
|
-
},
|
|
77
|
-
operationContext,
|
|
78
|
-
schema.toGraphQLJSSchema(),
|
|
79
|
-
apiSchema,
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
return { ...result, queryPlan, operation };
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function buildLocalService(modules: GraphQLSchemaModule[]) {
|
|
86
|
-
const schema = buildSubgraphSchema(modules);
|
|
87
|
-
return new LocalGraphQLDataSource(schema);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function getFederatedTestingSchema(services: ServiceDefinitionModule[] = fixtures) {
|
|
91
|
-
const compositionResult = composeServices(services);
|
|
92
|
-
if (compositionResult.errors) {
|
|
93
|
-
throw new GraphQLSchemaValidationError(compositionResult.errors);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const queryPlanner = new QueryPlanner(compositionResult.schema);
|
|
97
|
-
const schema = buildSchema(compositionResult.supergraphSdl);
|
|
98
|
-
|
|
99
|
-
const serviceMap = Object.fromEntries(
|
|
100
|
-
services.map((service) => [
|
|
101
|
-
service.name,
|
|
102
|
-
buildLocalService([service]),
|
|
103
|
-
]),
|
|
104
|
-
);
|
|
105
|
-
return { serviceMap, schema, queryPlanner };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export function getTestingSupergraphSdl(services: typeof fixtures = fixtures) {
|
|
109
|
-
const compositionResult = composeServices(services);
|
|
110
|
-
if (!compositionResult.errors) {
|
|
111
|
-
return compositionResult.supergraphSdl;
|
|
112
|
-
}
|
|
113
|
-
throw new Error(`Testing fixtures don't compose properly!\nCauses:\n${compositionResult.errors.join('\n\n')}`);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export function wait(ms: number, toResolveTo?: any) {
|
|
117
|
-
return new Promise((r) => setTimeout(() => r(toResolveTo), ms));
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export function printPlan(queryPlan: QueryPlan): string {
|
|
121
|
-
return prettyFormat(queryPlan, {
|
|
122
|
-
plugins: [queryPlanSerializer, astSerializer],
|
|
123
|
-
});
|
|
124
|
-
}
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
-
|
|
3
|
-
exports[`opentelemetry receives spans on fetch failure 1`] = `
|
|
4
|
-
[
|
|
5
|
-
{
|
|
6
|
-
"name": "gateway.request",
|
|
7
|
-
"attributes": {
|
|
8
|
-
"operationName": "GetProduct"
|
|
9
|
-
},
|
|
10
|
-
"children": [
|
|
11
|
-
{
|
|
12
|
-
"name": "gateway.validate",
|
|
13
|
-
"attributes": {},
|
|
14
|
-
"children": [],
|
|
15
|
-
"status": {
|
|
16
|
-
"code": 0
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
"name": "gateway.plan",
|
|
21
|
-
"attributes": {},
|
|
22
|
-
"children": [],
|
|
23
|
-
"status": {
|
|
24
|
-
"code": 0
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"name": "gateway.execute",
|
|
29
|
-
"attributes": {},
|
|
30
|
-
"children": [
|
|
31
|
-
{
|
|
32
|
-
"name": "gateway.fetch",
|
|
33
|
-
"attributes": {
|
|
34
|
-
"service": "product"
|
|
35
|
-
},
|
|
36
|
-
"children": [],
|
|
37
|
-
"status": {
|
|
38
|
-
"code": 2
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"name": "gateway.postprocessing",
|
|
43
|
-
"attributes": {},
|
|
44
|
-
"children": [],
|
|
45
|
-
"status": {
|
|
46
|
-
"code": 0
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
],
|
|
50
|
-
"status": {
|
|
51
|
-
"code": 2
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
],
|
|
55
|
-
"status": {
|
|
56
|
-
"code": 2
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
]
|
|
60
|
-
`;
|
|
61
|
-
|
|
62
|
-
exports[`opentelemetry with local data receives spans on plan failure 1`] = `
|
|
63
|
-
[
|
|
64
|
-
{
|
|
65
|
-
"name": "gateway.request",
|
|
66
|
-
"attributes": {
|
|
67
|
-
"operationName": "GetProduct"
|
|
68
|
-
},
|
|
69
|
-
"children": [
|
|
70
|
-
{
|
|
71
|
-
"name": "gateway.validate",
|
|
72
|
-
"attributes": {},
|
|
73
|
-
"children": [],
|
|
74
|
-
"status": {
|
|
75
|
-
"code": 0
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"name": "gateway.plan",
|
|
80
|
-
"attributes": {},
|
|
81
|
-
"children": [],
|
|
82
|
-
"status": {
|
|
83
|
-
"code": 2
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
],
|
|
87
|
-
"status": {
|
|
88
|
-
"code": 2
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
]
|
|
92
|
-
`;
|
|
93
|
-
|
|
94
|
-
exports[`opentelemetry with local data receives spans on success 1`] = `
|
|
95
|
-
[
|
|
96
|
-
{
|
|
97
|
-
"name": "gateway.request",
|
|
98
|
-
"attributes": {
|
|
99
|
-
"operationName": "GetProduct"
|
|
100
|
-
},
|
|
101
|
-
"children": [
|
|
102
|
-
{
|
|
103
|
-
"name": "gateway.validate",
|
|
104
|
-
"attributes": {},
|
|
105
|
-
"children": [],
|
|
106
|
-
"status": {
|
|
107
|
-
"code": 0
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
"name": "gateway.plan",
|
|
112
|
-
"attributes": {},
|
|
113
|
-
"children": [],
|
|
114
|
-
"status": {
|
|
115
|
-
"code": 0
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
"name": "gateway.execute",
|
|
120
|
-
"attributes": {},
|
|
121
|
-
"children": [
|
|
122
|
-
{
|
|
123
|
-
"name": "gateway.fetch",
|
|
124
|
-
"attributes": {
|
|
125
|
-
"service": "product"
|
|
126
|
-
},
|
|
127
|
-
"children": [],
|
|
128
|
-
"status": {
|
|
129
|
-
"code": 0
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
"name": "gateway.fetch",
|
|
134
|
-
"attributes": {
|
|
135
|
-
"service": "books"
|
|
136
|
-
},
|
|
137
|
-
"children": [],
|
|
138
|
-
"status": {
|
|
139
|
-
"code": 0
|
|
140
|
-
}
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
"name": "gateway.fetch",
|
|
144
|
-
"attributes": {
|
|
145
|
-
"service": "product"
|
|
146
|
-
},
|
|
147
|
-
"children": [],
|
|
148
|
-
"status": {
|
|
149
|
-
"code": 0
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
"name": "gateway.postprocessing",
|
|
154
|
-
"attributes": {},
|
|
155
|
-
"children": [],
|
|
156
|
-
"status": {
|
|
157
|
-
"code": 0
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
],
|
|
161
|
-
"status": {
|
|
162
|
-
"code": 0
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
],
|
|
166
|
-
"status": {
|
|
167
|
-
"code": 0
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
]
|
|
171
|
-
`;
|
|
172
|
-
|
|
173
|
-
exports[`opentelemetry with local data receives spans on validation failure 1`] = `
|
|
174
|
-
[
|
|
175
|
-
{
|
|
176
|
-
"name": "gateway.request",
|
|
177
|
-
"attributes": {
|
|
178
|
-
"operationName": "InvalidVariables"
|
|
179
|
-
},
|
|
180
|
-
"children": [
|
|
181
|
-
{
|
|
182
|
-
"name": "gateway.validate",
|
|
183
|
-
"attributes": {},
|
|
184
|
-
"children": [],
|
|
185
|
-
"status": {
|
|
186
|
-
"code": 2
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
],
|
|
190
|
-
"status": {
|
|
191
|
-
"code": 2
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
]
|
|
195
|
-
`;
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import nock from 'nock';
|
|
2
|
-
|
|
3
|
-
import { ApolloServer } from '@apollo/server';
|
|
4
|
-
|
|
5
|
-
import { RemoteGraphQLDataSource } from '../../datasources/RemoteGraphQLDataSource';
|
|
6
|
-
import { ApolloGateway, SERVICE_DEFINITION_QUERY } from '../../';
|
|
7
|
-
import { fixtures } from 'apollo-federation-integration-testsuite';
|
|
8
|
-
import { GraphQLDataSourceRequestKind } from '../../datasources/types';
|
|
9
|
-
import { nockAfterEach, nockBeforeEach } from '../nockAssertions';
|
|
10
|
-
import { unwrapSingleResultKind } from '../gateway/testUtils';
|
|
11
|
-
|
|
12
|
-
beforeEach(nockBeforeEach);
|
|
13
|
-
afterEach(nockAfterEach);
|
|
14
|
-
|
|
15
|
-
const replyHeaders = {
|
|
16
|
-
'content-type': 'application/json',
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
it('calls buildService only once per service', async () => {
|
|
20
|
-
nock('https://api.example.com')
|
|
21
|
-
.post('/foo')
|
|
22
|
-
.reply(
|
|
23
|
-
200,
|
|
24
|
-
{
|
|
25
|
-
data: { _service: { sdl: `extend type Query { thing: String }` } },
|
|
26
|
-
},
|
|
27
|
-
replyHeaders,
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
const buildServiceSpy = jest.fn(() => {
|
|
31
|
-
return new RemoteGraphQLDataSource({
|
|
32
|
-
url: 'https://api.example.com/foo',
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const gateway = new ApolloGateway({
|
|
37
|
-
serviceList: [{ name: 'foo', url: 'https://api.example.com/foo' }],
|
|
38
|
-
buildService: buildServiceSpy,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
await gateway.load();
|
|
42
|
-
|
|
43
|
-
expect(buildServiceSpy).toHaveBeenCalledTimes(1);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('correctly passes the context from ApolloServer to datasources', async () => {
|
|
47
|
-
const gateway = new ApolloGateway({
|
|
48
|
-
localServiceList: fixtures,
|
|
49
|
-
buildService: (_service) => {
|
|
50
|
-
return new RemoteGraphQLDataSource({
|
|
51
|
-
url: 'https://api.example.com/foo',
|
|
52
|
-
willSendRequest: (options) => {
|
|
53
|
-
if (
|
|
54
|
-
options.kind === GraphQLDataSourceRequestKind.INCOMING_OPERATION
|
|
55
|
-
) {
|
|
56
|
-
options.request.http?.headers.set(
|
|
57
|
-
'x-user-id',
|
|
58
|
-
options.context.userId,
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const server = new ApolloServer({
|
|
67
|
-
gateway,
|
|
68
|
-
});
|
|
69
|
-
await server.start();
|
|
70
|
-
|
|
71
|
-
const query = `#graphql
|
|
72
|
-
{
|
|
73
|
-
me {
|
|
74
|
-
username
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
`;
|
|
78
|
-
|
|
79
|
-
nock('https://api.example.com', {
|
|
80
|
-
reqheaders: {
|
|
81
|
-
'x-user-id': '1234',
|
|
82
|
-
},
|
|
83
|
-
})
|
|
84
|
-
.post('/foo', {
|
|
85
|
-
query: `{me{username}}`,
|
|
86
|
-
variables: {},
|
|
87
|
-
})
|
|
88
|
-
.reply(
|
|
89
|
-
200,
|
|
90
|
-
{
|
|
91
|
-
data: { me: { username: '@apollo-user' } },
|
|
92
|
-
},
|
|
93
|
-
replyHeaders,
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
const result = await server.executeOperation(
|
|
97
|
-
{
|
|
98
|
-
query,
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
contextValue: {
|
|
102
|
-
userId: '1234',
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
const { data, errors } = unwrapSingleResultKind(result);
|
|
108
|
-
expect(errors).toBeUndefined();
|
|
109
|
-
expect(data).toEqual({
|
|
110
|
-
me: { username: '@apollo-user' },
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
function createSdlData(sdl: string): [number, any, Record<string, string>] {
|
|
115
|
-
return [
|
|
116
|
-
200,
|
|
117
|
-
{
|
|
118
|
-
data: {
|
|
119
|
-
_service: {
|
|
120
|
-
sdl: sdl,
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
replyHeaders,
|
|
125
|
-
];
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
it('makes enhanced introspection request using datasource', async () => {
|
|
129
|
-
nock('https://api.example.com', {
|
|
130
|
-
reqheaders: {
|
|
131
|
-
'custom-header': 'some-custom-value',
|
|
132
|
-
},
|
|
133
|
-
})
|
|
134
|
-
.post('/override', {
|
|
135
|
-
query: SERVICE_DEFINITION_QUERY,
|
|
136
|
-
})
|
|
137
|
-
.reply(...createSdlData('extend type Query { one: String }'));
|
|
138
|
-
|
|
139
|
-
const gateway = new ApolloGateway({
|
|
140
|
-
serviceList: [
|
|
141
|
-
{
|
|
142
|
-
name: 'one',
|
|
143
|
-
url: 'https://api.example.com/one',
|
|
144
|
-
},
|
|
145
|
-
],
|
|
146
|
-
buildService: (_service) => {
|
|
147
|
-
return new RemoteGraphQLDataSource({
|
|
148
|
-
url: 'https://api.example.com/override',
|
|
149
|
-
willSendRequest: ({ request }) => {
|
|
150
|
-
request.http?.headers.set('custom-header', 'some-custom-value');
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
await gateway.load();
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('customizes request on a per-service basis', async () => {
|
|
160
|
-
for (const subgraph of ['one', 'two', 'three']) {
|
|
161
|
-
nock('https://api.example.com', {
|
|
162
|
-
reqheaders: {
|
|
163
|
-
'service-name': subgraph,
|
|
164
|
-
},
|
|
165
|
-
})
|
|
166
|
-
.post(`/${subgraph}`, {
|
|
167
|
-
query: SERVICE_DEFINITION_QUERY,
|
|
168
|
-
})
|
|
169
|
-
.reply(...createSdlData(`extend type Query { ${subgraph}: String }`));
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const gateway = new ApolloGateway({
|
|
173
|
-
serviceList: [
|
|
174
|
-
{
|
|
175
|
-
name: 'one',
|
|
176
|
-
url: 'https://api.example.com/one',
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
name: 'two',
|
|
180
|
-
url: 'https://api.example.com/two',
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
name: 'three',
|
|
184
|
-
url: 'https://api.example.com/three',
|
|
185
|
-
},
|
|
186
|
-
],
|
|
187
|
-
buildService: (service) => {
|
|
188
|
-
return new RemoteGraphQLDataSource({
|
|
189
|
-
url: service.url,
|
|
190
|
-
willSendRequest: ({ request }) => {
|
|
191
|
-
request.http?.headers.set('service-name', service.name);
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
},
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
await gateway.load();
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it('does not share service definition cache between gateways', async () => {
|
|
201
|
-
let updates = 0;
|
|
202
|
-
const updateObserver: any = (..._args: any[]) => {
|
|
203
|
-
updates += 1;
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
function nockSDLFetchOnce() {
|
|
207
|
-
nock('https://api.example.com')
|
|
208
|
-
.post('/repeat', {
|
|
209
|
-
query: SERVICE_DEFINITION_QUERY,
|
|
210
|
-
})
|
|
211
|
-
.reply(...createSdlData('extend type Query { repeat: String }'));
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Initialize first gateway
|
|
215
|
-
{
|
|
216
|
-
nockSDLFetchOnce();
|
|
217
|
-
|
|
218
|
-
const gateway = new ApolloGateway({
|
|
219
|
-
serviceList: [
|
|
220
|
-
{
|
|
221
|
-
name: 'repeat',
|
|
222
|
-
url: 'https://api.example.com/repeat',
|
|
223
|
-
},
|
|
224
|
-
],
|
|
225
|
-
experimental_didUpdateSupergraph: updateObserver,
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
await gateway.load();
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Initialize second gateway
|
|
232
|
-
{
|
|
233
|
-
nockSDLFetchOnce();
|
|
234
|
-
|
|
235
|
-
const gateway = new ApolloGateway({
|
|
236
|
-
serviceList: [
|
|
237
|
-
{
|
|
238
|
-
name: 'repeat',
|
|
239
|
-
url: 'https://api.example.com/repeat',
|
|
240
|
-
},
|
|
241
|
-
],
|
|
242
|
-
experimental_didUpdateSupergraph: updateObserver,
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
await gateway.load();
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
expect(updates).toEqual(2);
|
|
249
|
-
});
|