@apollo/gateway 0.300.0-alpha.2 → 2.0.0-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/LICENSE +95 -0
- package/README.md +1 -1
- package/dist/__generated__/graphqlTypes.d.ts +130 -0
- package/dist/__generated__/graphqlTypes.d.ts.map +1 -0
- package/dist/__generated__/graphqlTypes.js +25 -0
- package/dist/__generated__/graphqlTypes.js.map +1 -0
- package/dist/config.d.ts +104 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +47 -0
- package/dist/config.js.map +1 -0
- package/dist/datasources/LocalGraphQLDataSource.d.ts +3 -3
- package/dist/datasources/LocalGraphQLDataSource.d.ts.map +1 -1
- package/dist/datasources/LocalGraphQLDataSource.js +5 -5
- package/dist/datasources/LocalGraphQLDataSource.js.map +1 -1
- package/dist/datasources/RemoteGraphQLDataSource.d.ts +6 -4
- package/dist/datasources/RemoteGraphQLDataSource.d.ts.map +1 -1
- package/dist/datasources/RemoteGraphQLDataSource.js +60 -17
- package/dist/datasources/RemoteGraphQLDataSource.js.map +1 -1
- package/dist/datasources/index.d.ts +1 -1
- package/dist/datasources/index.d.ts.map +1 -1
- package/dist/datasources/index.js +1 -0
- package/dist/datasources/index.js.map +1 -1
- package/dist/datasources/parseCacheControlHeader.d.ts +2 -0
- package/dist/datasources/parseCacheControlHeader.d.ts.map +1 -0
- package/dist/datasources/parseCacheControlHeader.js +16 -0
- package/dist/datasources/parseCacheControlHeader.js.map +1 -0
- package/dist/datasources/types.d.ts +16 -1
- package/dist/datasources/types.d.ts.map +1 -1
- package/dist/datasources/types.js +7 -0
- package/dist/datasources/types.js.map +1 -1
- package/dist/executeQueryPlan.d.ts +2 -1
- package/dist/executeQueryPlan.d.ts.map +1 -1
- package/dist/executeQueryPlan.js +199 -112
- package/dist/executeQueryPlan.js.map +1 -1
- package/dist/index.d.ts +62 -80
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +543 -234
- package/dist/index.js.map +1 -1
- package/dist/loadServicesFromRemoteEndpoint.d.ts +9 -9
- package/dist/loadServicesFromRemoteEndpoint.d.ts.map +1 -1
- package/dist/loadServicesFromRemoteEndpoint.js +13 -8
- package/dist/loadServicesFromRemoteEndpoint.js.map +1 -1
- package/dist/loadSupergraphSdlFromStorage.d.ts +13 -0
- package/dist/loadSupergraphSdlFromStorage.d.ts.map +1 -0
- package/dist/loadSupergraphSdlFromStorage.js +101 -0
- package/dist/loadSupergraphSdlFromStorage.js.map +1 -0
- package/dist/operationContext.d.ts +17 -0
- package/dist/operationContext.d.ts.map +1 -0
- package/dist/operationContext.js +42 -0
- package/dist/operationContext.js.map +1 -0
- package/dist/outOfBandReporter.d.ts +15 -0
- package/dist/outOfBandReporter.d.ts.map +1 -0
- package/dist/outOfBandReporter.js +88 -0
- package/dist/outOfBandReporter.js.map +1 -0
- package/dist/utilities/array.d.ts +1 -2
- package/dist/utilities/array.d.ts.map +1 -1
- package/dist/utilities/array.js +7 -14
- package/dist/utilities/array.js.map +1 -1
- package/dist/utilities/assert.d.ts +2 -0
- package/dist/utilities/assert.d.ts.map +1 -0
- package/dist/utilities/assert.js +10 -0
- package/dist/utilities/assert.js.map +1 -0
- package/dist/utilities/cleanErrorOfInaccessibleNames.d.ts +3 -0
- package/dist/utilities/cleanErrorOfInaccessibleNames.d.ts.map +1 -0
- package/dist/utilities/cleanErrorOfInaccessibleNames.js +27 -0
- package/dist/utilities/cleanErrorOfInaccessibleNames.js.map +1 -0
- package/dist/utilities/deepMerge.js +2 -2
- package/dist/utilities/deepMerge.js.map +1 -1
- package/dist/utilities/graphql.d.ts +1 -4
- package/dist/utilities/graphql.d.ts.map +1 -1
- package/dist/utilities/graphql.js +3 -36
- package/dist/utilities/graphql.js.map +1 -1
- package/dist/utilities/opentelemetry.d.ts +10 -0
- package/dist/utilities/opentelemetry.d.ts.map +1 -0
- package/dist/utilities/opentelemetry.js +19 -0
- package/dist/utilities/opentelemetry.js.map +1 -0
- package/package.json +30 -21
- package/src/__generated__/graphqlTypes.ts +140 -0
- package/src/__mocks__/apollo-server-env.ts +56 -0
- package/src/__mocks__/make-fetch-happen-fetcher.ts +55 -0
- package/src/__mocks__/tsconfig.json +7 -0
- package/src/__tests__/build-query-plan.feature +40 -311
- package/src/__tests__/buildQueryPlan.test.ts +246 -426
- package/src/__tests__/executeQueryPlan.test.ts +1691 -194
- package/src/__tests__/execution-utils.ts +33 -26
- package/src/__tests__/gateway/__snapshots__/opentelemetry.test.ts.snap +195 -0
- package/src/__tests__/gateway/buildService.test.ts +16 -19
- package/src/__tests__/gateway/composedSdl.test.ts +44 -0
- package/src/__tests__/gateway/endToEnd.test.ts +166 -0
- package/src/__tests__/gateway/executor.test.ts +49 -43
- package/src/__tests__/gateway/lifecycle-hooks.test.ts +58 -29
- package/src/__tests__/gateway/opentelemetry.test.ts +123 -0
- package/src/__tests__/gateway/queryPlanCache.test.ts +19 -20
- package/src/__tests__/gateway/reporting.test.ts +76 -55
- package/src/__tests__/integration/abstract-types.test.ts +1086 -22
- package/src/__tests__/integration/aliases.test.ts +5 -6
- package/src/__tests__/integration/boolean.test.ts +40 -38
- package/src/__tests__/integration/complex-key.test.ts +41 -56
- package/src/__tests__/integration/configuration.test.ts +321 -0
- package/src/__tests__/integration/custom-directives.test.ts +61 -46
- package/src/__tests__/integration/fragments.test.ts +8 -2
- package/src/__tests__/integration/list-key.test.ts +2 -2
- package/src/__tests__/integration/logger.test.ts +2 -2
- package/src/__tests__/integration/multiple-key.test.ts +11 -12
- package/src/__tests__/integration/mutations.test.ts +8 -5
- package/src/__tests__/integration/networkRequests.test.ts +447 -289
- package/src/__tests__/integration/nockMocks.ts +95 -66
- package/src/__tests__/integration/provides.test.ts +9 -6
- package/src/__tests__/integration/requires.test.ts +17 -15
- package/src/__tests__/integration/scope.test.ts +557 -0
- package/src/__tests__/integration/unions.test.ts +1 -1
- package/src/__tests__/integration/value-types.test.ts +35 -32
- package/src/__tests__/integration/variables.test.ts +8 -2
- package/src/__tests__/loadServicesFromRemoteEndpoint.test.ts +6 -2
- package/src/__tests__/loadSupergraphSdlFromStorage.test.ts +694 -0
- package/src/__tests__/queryPlanCucumber.test.ts +11 -61
- package/src/__tests__/testSetup.ts +1 -4
- package/src/__tests__/tsconfig.json +2 -1
- package/src/config.ts +225 -0
- package/src/core/__tests__/core.test.ts +412 -0
- package/src/datasources/LocalGraphQLDataSource.ts +9 -10
- package/src/datasources/RemoteGraphQLDataSource.ts +117 -43
- package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +11 -4
- package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +148 -79
- package/src/datasources/__tests__/tsconfig.json +4 -2
- package/src/datasources/index.ts +1 -1
- package/src/datasources/parseCacheControlHeader.ts +43 -0
- package/src/datasources/types.ts +47 -2
- package/src/executeQueryPlan.ts +264 -153
- package/src/index.ts +925 -480
- package/src/loadServicesFromRemoteEndpoint.ts +24 -17
- package/src/loadSupergraphSdlFromStorage.ts +140 -0
- package/src/make-fetch-happen.d.ts +2 -2
- package/src/operationContext.ts +70 -0
- package/src/outOfBandReporter.ts +128 -0
- package/src/utilities/__tests__/cleanErrorOfInaccessibleElements.test.ts +104 -0
- package/src/utilities/__tests__/tsconfig.json +8 -0
- package/src/utilities/array.ts +6 -28
- package/src/utilities/assert.ts +14 -0
- package/src/utilities/cleanErrorOfInaccessibleNames.ts +29 -0
- package/src/utilities/graphql.ts +0 -64
- package/src/utilities/opentelemetry.ts +13 -0
- package/CHANGELOG.md +0 -226
- package/LICENSE.md +0 -20
- package/dist/FieldSet.d.ts +0 -18
- package/dist/FieldSet.d.ts.map +0 -1
- package/dist/FieldSet.js +0 -96
- package/dist/FieldSet.js.map +0 -1
- package/dist/QueryPlan.d.ts +0 -41
- package/dist/QueryPlan.d.ts.map +0 -1
- package/dist/QueryPlan.js +0 -15
- package/dist/QueryPlan.js.map +0 -1
- package/dist/buildQueryPlan.d.ts +0 -44
- package/dist/buildQueryPlan.d.ts.map +0 -1
- package/dist/buildQueryPlan.js +0 -670
- package/dist/buildQueryPlan.js.map +0 -1
- package/dist/loadServicesFromStorage.d.ts +0 -21
- package/dist/loadServicesFromStorage.d.ts.map +0 -1
- package/dist/loadServicesFromStorage.js +0 -64
- package/dist/loadServicesFromStorage.js.map +0 -1
- package/dist/snapshotSerializers/astSerializer.d.ts +0 -3
- package/dist/snapshotSerializers/astSerializer.d.ts.map +0 -1
- package/dist/snapshotSerializers/astSerializer.js +0 -14
- package/dist/snapshotSerializers/astSerializer.js.map +0 -1
- package/dist/snapshotSerializers/index.d.ts +0 -13
- package/dist/snapshotSerializers/index.d.ts.map +0 -1
- package/dist/snapshotSerializers/index.js +0 -15
- package/dist/snapshotSerializers/index.js.map +0 -1
- package/dist/snapshotSerializers/queryPlanSerializer.d.ts +0 -3
- package/dist/snapshotSerializers/queryPlanSerializer.d.ts.map +0 -1
- package/dist/snapshotSerializers/queryPlanSerializer.js +0 -78
- package/dist/snapshotSerializers/queryPlanSerializer.js.map +0 -1
- package/dist/snapshotSerializers/selectionSetSerializer.d.ts +0 -3
- package/dist/snapshotSerializers/selectionSetSerializer.d.ts.map +0 -1
- package/dist/snapshotSerializers/selectionSetSerializer.js +0 -12
- package/dist/snapshotSerializers/selectionSetSerializer.js.map +0 -1
- package/dist/snapshotSerializers/typeSerializer.d.ts +0 -3
- package/dist/snapshotSerializers/typeSerializer.d.ts.map +0 -1
- package/dist/snapshotSerializers/typeSerializer.js +0 -12
- package/dist/snapshotSerializers/typeSerializer.js.map +0 -1
- package/dist/utilities/MultiMap.d.ts +0 -4
- package/dist/utilities/MultiMap.d.ts.map +0 -1
- package/dist/utilities/MultiMap.js +0 -17
- package/dist/utilities/MultiMap.js.map +0 -1
- package/src/FieldSet.ts +0 -169
- package/src/QueryPlan.ts +0 -57
- package/src/__tests__/matchers/toCallService.ts +0 -105
- package/src/__tests__/matchers/toHaveBeenCalledBefore.ts +0 -40
- package/src/__tests__/matchers/toHaveFetched.ts +0 -81
- package/src/__tests__/matchers/toMatchAST.ts +0 -64
- package/src/buildQueryPlan.ts +0 -1190
- package/src/loadServicesFromStorage.ts +0 -170
- package/src/snapshotSerializers/astSerializer.ts +0 -21
- package/src/snapshotSerializers/index.ts +0 -21
- package/src/snapshotSerializers/queryPlanSerializer.ts +0 -144
- package/src/snapshotSerializers/selectionSetSerializer.ts +0 -13
- package/src/snapshotSerializers/typeSerializer.ts +0 -11
- package/src/utilities/MultiMap.ts +0 -11
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import gql from 'graphql-tag';
|
|
2
|
-
import { GraphQLSchemaValidationError } from 'apollo-graphql';
|
|
3
2
|
import { defineFeature, loadFeature } from 'jest-cucumber';
|
|
4
|
-
import { DocumentNode
|
|
3
|
+
import { DocumentNode } from 'graphql';
|
|
5
4
|
|
|
6
|
-
import { QueryPlan } from '
|
|
7
|
-
import { buildQueryPlan, buildOperationContext, BuildQueryPlanOptions } from '../buildQueryPlan';
|
|
5
|
+
import { QueryPlan } from '@apollo/query-planner';
|
|
8
6
|
import { getFederatedTestingSchema } from './execution-utils';
|
|
7
|
+
import { operationFromDocument } from '@apollo/federation-internals';
|
|
9
8
|
|
|
10
9
|
const buildQueryPlanFeature = loadFeature(
|
|
11
|
-
'./
|
|
10
|
+
'./gateway-js/src/__tests__/build-query-plan.feature'
|
|
12
11
|
);
|
|
13
12
|
|
|
14
13
|
|
|
@@ -19,40 +18,26 @@ const features = [
|
|
|
19
18
|
features.forEach((feature) => {
|
|
20
19
|
defineFeature(feature, (test) => {
|
|
21
20
|
feature.scenarios.forEach((scenario) => {
|
|
22
|
-
test(scenario.title, async ({ given,
|
|
23
|
-
let
|
|
21
|
+
test(scenario.title, async ({ given, then }) => {
|
|
22
|
+
let operationDocument: DocumentNode;
|
|
24
23
|
let queryPlan: QueryPlan;
|
|
25
|
-
let options: BuildQueryPlanOptions = { autoFragmentization: false };
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (errors && errors.length > 0) {
|
|
30
|
-
throw new GraphQLSchemaValidationError(errors);
|
|
31
|
-
}
|
|
25
|
+
// throws on composition errors
|
|
26
|
+
const { schema, queryPlanner } = getFederatedTestingSchema();
|
|
32
27
|
|
|
33
28
|
const givenQuery = () => {
|
|
34
29
|
given(/^query$/im, (operation: string) => {
|
|
35
|
-
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const whenUsingAutoFragmentization = () => {
|
|
40
|
-
when(/using autofragmentization/i, () => {
|
|
41
|
-
options = { autoFragmentization: true };
|
|
30
|
+
operationDocument = gql(operation);
|
|
42
31
|
})
|
|
43
32
|
}
|
|
44
33
|
|
|
45
34
|
const thenQueryPlanShouldBe = () => {
|
|
46
35
|
then(/^query plan$/i, (expectedQueryPlan: string) => {
|
|
47
|
-
queryPlan = buildQueryPlan(
|
|
48
|
-
buildOperationContext(schema, query, undefined),
|
|
49
|
-
options
|
|
50
|
-
);
|
|
36
|
+
queryPlan = queryPlanner.buildQueryPlan(operationFromDocument(schema, operationDocument));
|
|
51
37
|
|
|
52
|
-
const serializedPlan = JSON.parse(JSON.stringify(queryPlan, serializeQueryPlanNode));
|
|
53
38
|
const parsedExpectedPlan = JSON.parse(expectedQueryPlan);
|
|
54
39
|
|
|
55
|
-
expect(
|
|
40
|
+
expect(queryPlan).toEqual(parsedExpectedPlan);
|
|
56
41
|
})
|
|
57
42
|
}
|
|
58
43
|
|
|
@@ -61,7 +46,6 @@ features.forEach((feature) => {
|
|
|
61
46
|
scenario.steps.forEach(({ stepText }) => {
|
|
62
47
|
const title = stepText.toLocaleLowerCase();
|
|
63
48
|
if (title === "query") givenQuery();
|
|
64
|
-
else if (title === "using autofragmentization") whenUsingAutoFragmentization();
|
|
65
49
|
else if (title === "query plan") thenQueryPlanShouldBe();
|
|
66
50
|
else throw new Error(`Unrecognized steps used in "build-query-plan.feature"`);
|
|
67
51
|
});
|
|
@@ -69,37 +53,3 @@ features.forEach((feature) => {
|
|
|
69
53
|
});
|
|
70
54
|
});
|
|
71
55
|
});
|
|
72
|
-
|
|
73
|
-
const serializeQueryPlanNode = (k: string , v: any) => {
|
|
74
|
-
switch(k){
|
|
75
|
-
case "selectionSet":
|
|
76
|
-
case "internalFragments":
|
|
77
|
-
case "loc":
|
|
78
|
-
case "arguments":
|
|
79
|
-
case "directives":
|
|
80
|
-
case "source":
|
|
81
|
-
return undefined;
|
|
82
|
-
case "kind":
|
|
83
|
-
if(v === Kind.SELECTION_SET) return undefined;
|
|
84
|
-
return v;
|
|
85
|
-
case "variableUsages":
|
|
86
|
-
// TODO check this
|
|
87
|
-
return Object.keys(v);
|
|
88
|
-
case "typeCondition":
|
|
89
|
-
return v.name.value;
|
|
90
|
-
case "name":
|
|
91
|
-
return v.value;
|
|
92
|
-
case "requires":
|
|
93
|
-
return v?.selections;
|
|
94
|
-
default:
|
|
95
|
-
// replace source with operation
|
|
96
|
-
if(v?.kind === "Fetch"){
|
|
97
|
-
return { ...v, operation: v.source };
|
|
98
|
-
}
|
|
99
|
-
// replace selectionSet with selections[]
|
|
100
|
-
if(v?.kind === Kind.INLINE_FRAGMENT){
|
|
101
|
-
return { ...v, selections: v.selectionSet.selections }
|
|
102
|
-
}
|
|
103
|
-
return v;
|
|
104
|
-
}
|
|
105
|
-
}
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { GraphQLError, GraphQLSchema } from "graphql";
|
|
2
|
+
import { HeadersInit } from "node-fetch";
|
|
3
|
+
import { fetch } from 'apollo-server-env';
|
|
4
|
+
import { GraphQLRequestContextExecutionDidStart, Logger } from "apollo-server-types";
|
|
5
|
+
import { GraphQLDataSource } from './datasources/types';
|
|
6
|
+
import { QueryPlan } from '@apollo/query-planner';
|
|
7
|
+
import { OperationContext } from './operationContext';
|
|
8
|
+
import { ServiceMap } from './executeQueryPlan';
|
|
9
|
+
import { ServiceDefinition } from "@apollo/federation-internals";
|
|
10
|
+
|
|
11
|
+
export type ServiceEndpointDefinition = Pick<ServiceDefinition, 'name' | 'url'>;
|
|
12
|
+
|
|
13
|
+
export type Experimental_DidResolveQueryPlanCallback = ({
|
|
14
|
+
queryPlan,
|
|
15
|
+
serviceMap,
|
|
16
|
+
operationContext,
|
|
17
|
+
requestContext,
|
|
18
|
+
}: {
|
|
19
|
+
readonly queryPlan: QueryPlan;
|
|
20
|
+
readonly serviceMap: ServiceMap;
|
|
21
|
+
readonly operationContext: OperationContext;
|
|
22
|
+
readonly requestContext: GraphQLRequestContextExecutionDidStart<
|
|
23
|
+
Record<string, any>
|
|
24
|
+
>;
|
|
25
|
+
}) => void;
|
|
26
|
+
|
|
27
|
+
interface ImplementingServiceLocation {
|
|
28
|
+
name: string;
|
|
29
|
+
path: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface CompositionMetadata {
|
|
33
|
+
formatVersion: number;
|
|
34
|
+
id: string;
|
|
35
|
+
implementingServiceLocations: ImplementingServiceLocation[];
|
|
36
|
+
schemaHash: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type Experimental_DidFailCompositionCallback = ({
|
|
40
|
+
errors,
|
|
41
|
+
serviceList,
|
|
42
|
+
compositionMetadata,
|
|
43
|
+
}: {
|
|
44
|
+
readonly errors: GraphQLError[];
|
|
45
|
+
readonly serviceList: ServiceDefinition[];
|
|
46
|
+
readonly compositionMetadata?: CompositionMetadata;
|
|
47
|
+
}) => void;
|
|
48
|
+
|
|
49
|
+
export interface ServiceDefinitionCompositionInfo {
|
|
50
|
+
serviceDefinitions: ServiceDefinition[];
|
|
51
|
+
schema: GraphQLSchema;
|
|
52
|
+
compositionMetadata?: CompositionMetadata;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface SupergraphSdlCompositionInfo {
|
|
56
|
+
schema: GraphQLSchema;
|
|
57
|
+
compositionId: string;
|
|
58
|
+
supergraphSdl: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type CompositionInfo =
|
|
62
|
+
| ServiceDefinitionCompositionInfo
|
|
63
|
+
| SupergraphSdlCompositionInfo;
|
|
64
|
+
|
|
65
|
+
export type Experimental_DidUpdateCompositionCallback = (
|
|
66
|
+
currentConfig: CompositionInfo,
|
|
67
|
+
previousConfig?: CompositionInfo,
|
|
68
|
+
) => void;
|
|
69
|
+
|
|
70
|
+
export type CompositionUpdate = ServiceDefinitionUpdate | SupergraphSdlUpdate;
|
|
71
|
+
|
|
72
|
+
export interface ServiceDefinitionUpdate {
|
|
73
|
+
serviceDefinitions?: ServiceDefinition[];
|
|
74
|
+
compositionMetadata?: CompositionMetadata;
|
|
75
|
+
isNewSchema: boolean;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface SupergraphSdlUpdate {
|
|
79
|
+
id: string;
|
|
80
|
+
supergraphSdl: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function isSupergraphSdlUpdate(update: CompositionUpdate): update is SupergraphSdlUpdate {
|
|
84
|
+
return 'supergraphSdl' in update;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function isServiceDefinitionUpdate(
|
|
88
|
+
update: CompositionUpdate,
|
|
89
|
+
): update is ServiceDefinitionUpdate {
|
|
90
|
+
return 'isNewSchema' in update;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* **Note:** It's possible for a schema to be the same (`isNewSchema: false`) when
|
|
95
|
+
* `serviceDefinitions` have changed. For example, during type migration, the
|
|
96
|
+
* composed schema may be identical but the `serviceDefinitions` would differ
|
|
97
|
+
* since a type has moved from one service to another.
|
|
98
|
+
*/
|
|
99
|
+
export type Experimental_UpdateServiceDefinitions = (
|
|
100
|
+
config: DynamicGatewayConfig,
|
|
101
|
+
) => Promise<ServiceDefinitionUpdate>;
|
|
102
|
+
|
|
103
|
+
export type Experimental_UpdateSupergraphSdl = (
|
|
104
|
+
config: DynamicGatewayConfig,
|
|
105
|
+
) => Promise<SupergraphSdlUpdate>;
|
|
106
|
+
|
|
107
|
+
export type Experimental_UpdateComposition = (
|
|
108
|
+
config: DynamicGatewayConfig,
|
|
109
|
+
) => Promise<CompositionUpdate>;
|
|
110
|
+
|
|
111
|
+
interface GatewayConfigBase {
|
|
112
|
+
debug?: boolean;
|
|
113
|
+
logger?: Logger;
|
|
114
|
+
// TODO: expose the query plan in a more flexible JSON format in the future
|
|
115
|
+
// and remove this config option in favor of `exposeQueryPlan`. Playground
|
|
116
|
+
// should cutover to use the new option when it's built.
|
|
117
|
+
__exposeQueryPlanExperimental?: boolean;
|
|
118
|
+
buildService?: (definition: ServiceEndpointDefinition) => GraphQLDataSource;
|
|
119
|
+
|
|
120
|
+
// experimental observability callbacks
|
|
121
|
+
experimental_didResolveQueryPlan?: Experimental_DidResolveQueryPlanCallback;
|
|
122
|
+
experimental_didFailComposition?: Experimental_DidFailCompositionCallback;
|
|
123
|
+
experimental_didUpdateComposition?: Experimental_DidUpdateCompositionCallback;
|
|
124
|
+
experimental_pollInterval?: number;
|
|
125
|
+
experimental_approximateQueryPlanStoreMiB?: number;
|
|
126
|
+
experimental_autoFragmentization?: boolean;
|
|
127
|
+
fetcher?: typeof fetch;
|
|
128
|
+
serviceHealthCheck?: boolean;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface RemoteGatewayConfig extends GatewayConfigBase {
|
|
132
|
+
serviceList: ServiceEndpointDefinition[];
|
|
133
|
+
introspectionHeaders?:
|
|
134
|
+
| HeadersInit
|
|
135
|
+
| ((service: ServiceEndpointDefinition) => Promise<HeadersInit> | HeadersInit);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface ManagedGatewayConfig extends GatewayConfigBase {
|
|
139
|
+
/**
|
|
140
|
+
* This configuration option shouldn't be used unless by recommendation from
|
|
141
|
+
* Apollo staff.
|
|
142
|
+
*/
|
|
143
|
+
schemaConfigDeliveryEndpoint?: string;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface ManuallyManagedServiceDefsGatewayConfig extends GatewayConfigBase {
|
|
147
|
+
experimental_updateServiceDefinitions: Experimental_UpdateServiceDefinitions;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
interface ManuallyManagedSupergraphSdlGatewayConfig extends GatewayConfigBase {
|
|
151
|
+
experimental_updateSupergraphSdl: Experimental_UpdateSupergraphSdl
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
type ManuallyManagedGatewayConfig =
|
|
155
|
+
| ManuallyManagedServiceDefsGatewayConfig
|
|
156
|
+
| ManuallyManagedSupergraphSdlGatewayConfig;
|
|
157
|
+
|
|
158
|
+
interface LocalGatewayConfig extends GatewayConfigBase {
|
|
159
|
+
localServiceList: ServiceDefinition[];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
interface SupergraphSdlGatewayConfig extends GatewayConfigBase {
|
|
163
|
+
supergraphSdl: string;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export type StaticGatewayConfig = LocalGatewayConfig | SupergraphSdlGatewayConfig;
|
|
167
|
+
|
|
168
|
+
type DynamicGatewayConfig =
|
|
169
|
+
| ManagedGatewayConfig
|
|
170
|
+
| RemoteGatewayConfig
|
|
171
|
+
| ManuallyManagedGatewayConfig;
|
|
172
|
+
|
|
173
|
+
export type GatewayConfig = StaticGatewayConfig | DynamicGatewayConfig;
|
|
174
|
+
|
|
175
|
+
export function isLocalConfig(config: GatewayConfig): config is LocalGatewayConfig {
|
|
176
|
+
return 'localServiceList' in config;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function isRemoteConfig(config: GatewayConfig): config is RemoteGatewayConfig {
|
|
180
|
+
return 'serviceList' in config;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function isSupergraphSdlConfig(config: GatewayConfig): config is SupergraphSdlGatewayConfig {
|
|
184
|
+
return 'supergraphSdl' in config;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// A manually managed config means the user has provided a function which
|
|
188
|
+
// handles providing service definitions to the gateway.
|
|
189
|
+
export function isManuallyManagedConfig(
|
|
190
|
+
config: GatewayConfig,
|
|
191
|
+
): config is ManuallyManagedGatewayConfig {
|
|
192
|
+
return (
|
|
193
|
+
'experimental_updateServiceDefinitions' in config ||
|
|
194
|
+
'experimental_updateSupergraphSdl' in config
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Managed config strictly means managed by Studio
|
|
199
|
+
export function isManagedConfig(
|
|
200
|
+
config: GatewayConfig,
|
|
201
|
+
): config is ManagedGatewayConfig {
|
|
202
|
+
return (
|
|
203
|
+
'schemaConfigDeliveryEndpoint' in config ||
|
|
204
|
+
(!isRemoteConfig(config) &&
|
|
205
|
+
!isLocalConfig(config) &&
|
|
206
|
+
!isSupergraphSdlConfig(config) &&
|
|
207
|
+
!isManuallyManagedConfig(config))
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// A static config is one which loads synchronously on start and never updates
|
|
212
|
+
export function isStaticConfig(config: GatewayConfig): config is StaticGatewayConfig {
|
|
213
|
+
return isLocalConfig(config) || isSupergraphSdlConfig(config);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// A dynamic config is one which loads asynchronously and (can) update via polling
|
|
217
|
+
export function isDynamicConfig(
|
|
218
|
+
config: GatewayConfig,
|
|
219
|
+
): config is DynamicGatewayConfig {
|
|
220
|
+
return (
|
|
221
|
+
isRemoteConfig(config) ||
|
|
222
|
+
isManagedConfig(config) ||
|
|
223
|
+
isManuallyManagedConfig(config)
|
|
224
|
+
);
|
|
225
|
+
}
|