@apollo/gateway 0.51.0 → 0.52.0

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.
Files changed (36) hide show
  1. package/dist/config.d.ts +2 -2
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js.map +1 -1
  4. package/dist/datasources/LocalGraphQLDataSource.d.ts +2 -2
  5. package/dist/datasources/LocalGraphQLDataSource.d.ts.map +1 -1
  6. package/dist/datasources/LocalGraphQLDataSource.js +0 -2
  7. package/dist/datasources/LocalGraphQLDataSource.js.map +1 -1
  8. package/dist/datasources/RemoteGraphQLDataSource.d.ts +6 -6
  9. package/dist/datasources/RemoteGraphQLDataSource.d.ts.map +1 -1
  10. package/dist/datasources/RemoteGraphQLDataSource.js +12 -18
  11. package/dist/datasources/RemoteGraphQLDataSource.js.map +1 -1
  12. package/dist/datasources/types.d.ts +5 -5
  13. package/dist/datasources/types.d.ts.map +1 -1
  14. package/dist/executeQueryPlan.d.ts +3 -3
  15. package/dist/executeQueryPlan.d.ts.map +1 -1
  16. package/dist/executeQueryPlan.js.map +1 -1
  17. package/dist/index.d.ts +7 -8
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +10 -11
  20. package/dist/index.js.map +1 -1
  21. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.d.ts.map +1 -1
  22. package/dist/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.js.map +1 -1
  23. package/package.json +8 -10
  24. package/src/__generated__/graphqlTypes.ts +1 -1
  25. package/src/__tests__/executeQueryPlan.test.ts +14 -5
  26. package/src/__tests__/execution-utils.ts +3 -3
  27. package/src/__tests__/gateway/executor.test.ts +2 -2
  28. package/src/config.ts +2 -4
  29. package/src/datasources/LocalGraphQLDataSource.ts +2 -4
  30. package/src/datasources/RemoteGraphQLDataSource.ts +38 -42
  31. package/src/datasources/__tests__/LocalGraphQLDataSource.test.ts +2 -2
  32. package/src/datasources/__tests__/RemoteGraphQLDataSource.test.ts +14 -19
  33. package/src/datasources/types.ts +12 -5
  34. package/src/executeQueryPlan.ts +13 -17
  35. package/src/index.ts +21 -42
  36. package/src/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.ts +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"loadServicesFromRemoteEndpoint.js","sourceRoot":"","sources":["../../../src/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.ts"],"names":[],"mappings":";;;AACA,qCAAgC;AAChC,2CAAkD;AAClD,mDAA0F;AAC1F,6BAAiD;AAQ1C,KAAK,UAAU,8BAA8B,CAAC,EACnD,WAAW,EACX,8BAA8B,EAC9B,eAAe,GAOhB;IACC,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;QACvC,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;KACH;IAED,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE;QAC/E,IAAI,CAAC,GAAG,EAAE;YACR,MAAM,IAAI,KAAK,CACb,6BAA6B,IAAI,+BAA+B,CAAC,CAAC;SACrE;QAED,MAAM,OAAO,GAAmB;YAC9B,KAAK,EAAE,4BAAwB;YAC/B,IAAI,EAAE;gBACJ,GAAG;gBACH,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,IAAI,oBAAO,CAAC,MAAM,8BAA8B,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;aAC1E;SACF,CAAC;QAEF,OAAO,UAAU;aACd,OAAO,CAAC;YACP,IAAI,EAAE,oCAA4B,CAAC,cAAc;YACjD,OAAO;YACP,OAAO,EAAE,EAAE;SACZ,CAAC;aACD,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAqB,EAAE;YAC5C,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;gBACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAa,CAAC;gBAC7C,MAAM,kBAAkB,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAGrD,IAAI,kBAAkB,KAAK,QAAQ,EAAE;oBACnC,WAAW,GAAG,IAAI,CAAC;iBACpB;gBACD,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;gBACpC,OAAO;oBACL,IAAI;oBACJ,GAAG;oBACH,QAAQ,EAAE,IAAA,eAAK,EAAC,QAAQ,CAAC;iBAC1B,CAAC;aACH;YAED,MAAM,IAAI,KAAK,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,MAAM,YAAY,GAChB,0CAA0C,IAAI,QAAQ,GAAG,EAAE;gBAC3D,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAExD,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACnE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAA;AAC5C,CAAC;AAtED,wEAsEC"}
1
+ {"version":3,"file":"loadServicesFromRemoteEndpoint.js","sourceRoot":"","sources":["../../../src/supergraphManagers/IntrospectAndCompose/loadServicesFromRemoteEndpoint.ts"],"names":[],"mappings":";;;AAAA,qCAAgC;AAChC,2CAAkD;AAClD,mDAA0F;AAC1F,6BAAiD;AAS1C,KAAK,UAAU,8BAA8B,CAAC,EACnD,WAAW,EACX,8BAA8B,EAC9B,eAAe,GAOhB;IACC,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;QACvC,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;KACH;IAED,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE;QAC/E,IAAI,CAAC,GAAG,EAAE;YACR,MAAM,IAAI,KAAK,CACb,6BAA6B,IAAI,+BAA+B,CAAC,CAAC;SACrE;QAED,MAAM,OAAO,GAA0B;YACrC,KAAK,EAAE,4BAAwB;YAC/B,IAAI,EAAE;gBACJ,GAAG;gBACH,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,IAAI,oBAAO,CAAC,MAAM,8BAA8B,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;aAC1E;SACF,CAAC;QAEF,OAAO,UAAU;aACd,OAAO,CAAC;YACP,IAAI,EAAE,oCAA4B,CAAC,cAAc;YACjD,OAAO;YACP,OAAO,EAAE,EAAE;SACZ,CAAC;aACD,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAqB,EAAE;YAC5C,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;gBACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAa,CAAC;gBAC7C,MAAM,kBAAkB,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAGrD,IAAI,kBAAkB,KAAK,QAAQ,EAAE;oBACnC,WAAW,GAAG,IAAI,CAAC;iBACpB;gBACD,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;gBACpC,OAAO;oBACL,IAAI;oBACJ,GAAG;oBACH,QAAQ,EAAE,IAAA,eAAK,EAAC,QAAQ,CAAC;iBAC1B,CAAC;aACH;YAED,MAAM,IAAI,KAAK,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,MAAM,YAAY,GAChB,0CAA0C,IAAI,QAAQ,GAAG,EAAE;gBAC3D,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAExD,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACnE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAA;AAC5C,CAAC;AAtED,wEAsEC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apollo/gateway",
3
- "version": "0.51.0",
3
+ "version": "0.52.0",
4
4
  "description": "Apollo Gateway",
5
5
  "author": "Apollo <packages@apollographql.com>",
6
6
  "main": "dist/index.js",
@@ -26,26 +26,24 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@apollo/core-schema": "^0.2.0",
29
- "@apollo/federation": "^0.36.2",
30
- "@apollo/query-planner": "^0.10.2",
29
+ "@apollo/federation": "^0.37.0",
30
+ "@apollo/query-planner": "^0.11.0",
31
+ "@apollo/server-gateway-interface": "^1.0.1",
31
32
  "@apollo/utils.createhash": "^1.0.0",
32
33
  "@apollo/utils.fetcher": "^1.0.0",
33
34
  "@apollo/utils.logger": "^1.0.0",
34
35
  "@josephg/resolvable": "^1.0.1",
35
36
  "@opentelemetry/api": "^1.0.1",
36
- "@types/node-fetch": "2.6.1",
37
+ "@types/node-fetch": "2.6.2",
37
38
  "apollo-reporting-protobuf": "^0.8.0 || ^3.0.0",
38
- "apollo-server-caching": "^0.7.0 || ^3.0.0",
39
- "apollo-server-core": "^2.23.0 || ^3.0.0",
40
- "apollo-server-errors": "^2.5.0 || ^3.0.0",
41
- "apollo-server-types": "^0.9.0 || ^3.0.0",
42
39
  "async-retry": "^1.3.3",
43
40
  "loglevel": "^1.6.1",
41
+ "lru-cache": "^7.13.1",
44
42
  "make-fetch-happen": "^10.1.2",
45
- "pretty-format": "^27.4.6"
43
+ "pretty-format": "^28.0.0"
46
44
  },
47
45
  "peerDependencies": {
48
46
  "graphql": "^15.8.0 || ^16.0.0"
49
47
  },
50
- "gitHead": "bf11c7dbd65049d1cb0d91b148f181b89e51e157"
48
+ "gitHead": "302ecaeea4e20a4d594b92b94499d9e156f4cea6"
51
49
  }
@@ -10,7 +10,7 @@ export type Scalars = {
10
10
  Boolean: boolean;
11
11
  Int: number;
12
12
  Float: number;
13
- /** ISO 8601, extended format with nanoseconds, Zulu (or '[+-]seconds' for times relative to now) */
13
+ /** ISO 8601, extended format with nanoseconds, Zulu (or "[+-]seconds" as a string or number relative to now) */
14
14
  Timestamp: any;
15
15
  };
16
16
 
@@ -1,13 +1,12 @@
1
1
  import {
2
2
  buildClientSchema,
3
3
  getIntrospectionQuery,
4
+ GraphQLError,
4
5
  GraphQLObjectType,
5
6
  GraphQLSchema,
6
7
  print,
7
8
  } from 'graphql';
8
9
  import gql from 'graphql-tag';
9
- import { GraphQLRequestContext, VariableValues } from 'apollo-server-types';
10
- import { AuthenticationError } from 'apollo-server-core';
11
10
  import { buildOperationContext } from '../operationContext';
12
11
  import { executeQueryPlan } from '../executeQueryPlan';
13
12
  import { LocalGraphQLDataSource } from '../datasources/LocalGraphQLDataSource';
@@ -21,6 +20,7 @@ import { ApolloGateway } from '..';
21
20
  import { ApolloServerBase as ApolloServer } from 'apollo-server-core';
22
21
  import { getFederatedTestingSchema } from './execution-utils';
23
22
  import { addResolversToSchema, GraphQLResolverMap } from '@apollo/subgraph/src/schema-helper';
23
+ import {GatewayGraphQLRequestContext} from '@apollo/server-gateway-interface';
24
24
 
25
25
  expect.addSnapshotSerializer(astSerializer);
26
26
  expect.addSnapshotSerializer(queryPlanSerializer);
@@ -53,8 +53,8 @@ describe('executeQueryPlan', () => {
53
53
  });
54
54
 
55
55
  function buildRequestContext(
56
- variables: VariableValues = {},
57
- ): GraphQLRequestContext {
56
+ variables: Record<string, any> = {},
57
+ ): GatewayGraphQLRequestContext {
58
58
  // @ts-ignore
59
59
  return {
60
60
  cache: undefined as any,
@@ -101,7 +101,16 @@ describe('executeQueryPlan', () => {
101
101
  overrideResolversInService('accounts', {
102
102
  RootQuery: {
103
103
  me() {
104
- throw new AuthenticationError('Something went wrong');
104
+ // Must use old constructor for graphql@15 compat on v0.x branch.
105
+ throw new GraphQLError(
106
+ 'Something went wrong',
107
+ undefined,
108
+ undefined,
109
+ undefined,
110
+ undefined,
111
+ undefined,
112
+ { code: 'UNAUTHENTICATED' },
113
+ );
105
114
  },
106
115
  },
107
116
  });
@@ -2,7 +2,6 @@ import {
2
2
  GraphQLSchemaModule,
3
3
  GraphQLResolverMap,
4
4
  } from '@apollo/subgraph/src/schema-helper';
5
- import { GraphQLRequest, GraphQLExecutionResult } from 'apollo-server-types';
6
5
  import type { Logger } from '@apollo/utils.logger';
7
6
  import {
8
7
  composeAndValidate,
@@ -22,6 +21,7 @@ import { queryPlanSerializer, astSerializer } from 'apollo-federation-integratio
22
21
  import gql from 'graphql-tag';
23
22
  import { fixtures } from 'apollo-federation-integration-testsuite';
24
23
  import { parse } from 'graphql';
24
+ import { GatewayExecutionResult, GatewayGraphQLRequest } from '@apollo/server-gateway-interface';
25
25
 
26
26
  const prettyFormat = require('pretty-format');
27
27
 
@@ -39,10 +39,10 @@ export function overrideResolversInService(
39
39
  }
40
40
 
41
41
  export async function execute(
42
- request: GraphQLRequest,
42
+ request: GatewayGraphQLRequest,
43
43
  services: ServiceDefinitionModule[] = fixtures,
44
44
  logger: Logger = console,
45
- ): Promise<GraphQLExecutionResult & { queryPlan: QueryPlan }> {
45
+ ): Promise<GatewayExecutionResult & { queryPlan: QueryPlan }> {
46
46
  const serviceMap = Object.fromEntries(
47
47
  services.map(({ name, typeDefs, resolvers }) => {
48
48
  return [
@@ -48,7 +48,7 @@ describe('ApolloGateway executor', () => {
48
48
  variables: { first: '3' },
49
49
  },
50
50
  queryHash: 'hashed',
51
- context: null,
51
+ context: {},
52
52
  cache: {} as any,
53
53
  logger,
54
54
  });
@@ -83,7 +83,7 @@ describe('ApolloGateway executor', () => {
83
83
  document: gql(source),
84
84
  request: {},
85
85
  queryHash: 'hashed',
86
- context: null,
86
+ context: {},
87
87
  cache: {} as any,
88
88
  logger,
89
89
  });
package/src/config.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { GraphQLError, GraphQLSchema } from 'graphql';
2
2
  import { HeadersInit } from 'node-fetch';
3
- import { GraphQLRequestContextExecutionDidStart } from 'apollo-server-types';
3
+ import { GatewayGraphQLRequestContext } from '@apollo/server-gateway-interface';
4
4
  import type { Logger } from '@apollo/utils.logger';
5
5
  import { ServiceDefinition } from '@apollo/federation';
6
6
  import { GraphQLDataSource } from './datasources/types';
@@ -20,9 +20,7 @@ export type Experimental_DidResolveQueryPlanCallback = ({
20
20
  readonly queryPlan: QueryPlan;
21
21
  readonly serviceMap: ServiceMap;
22
22
  readonly operationContext: OperationContext;
23
- readonly requestContext: GraphQLRequestContextExecutionDidStart<
24
- Record<string, any>
25
- >;
23
+ readonly requestContext: GatewayGraphQLRequestContext;
26
24
  }) => void;
27
25
 
28
26
  interface ImplementingServiceLocation {
@@ -1,4 +1,4 @@
1
- import { GraphQLResponse } from 'apollo-server-types';
1
+ import { GatewayGraphQLResponse } from '@apollo/server-gateway-interface';
2
2
  import {
3
3
  GraphQLSchema,
4
4
  graphql,
@@ -6,7 +6,6 @@ import {
6
6
  DocumentNode,
7
7
  parse,
8
8
  } from 'graphql';
9
- import { enablePluginsForSchemaResolvers } from 'apollo-server-core/dist/utils/schemaInstrumentation';
10
9
  import { GraphQLDataSource, GraphQLDataSourceProcessOptions } from './types';
11
10
 
12
11
  export class LocalGraphQLDataSource<
@@ -14,13 +13,12 @@ export class LocalGraphQLDataSource<
14
13
  > implements GraphQLDataSource<TContext>
15
14
  {
16
15
  constructor(public readonly schema: GraphQLSchema) {
17
- enablePluginsForSchemaResolvers(schema);
18
16
  }
19
17
 
20
18
  async process({
21
19
  request,
22
20
  context,
23
- }: GraphQLDataSourceProcessOptions<TContext>): Promise<GraphQLResponse> {
21
+ }: GraphQLDataSourceProcessOptions<TContext>): Promise<GatewayGraphQLResponse> {
24
22
  return graphql({
25
23
  schema: this.schema,
26
24
  source: request.query!,
@@ -1,17 +1,3 @@
1
- import {
2
- GraphQLRequestContext,
3
- GraphQLResponse,
4
- ValueOrPromise,
5
- GraphQLRequest,
6
- CacheHint,
7
- CacheScope,
8
- CachePolicy,
9
- } from 'apollo-server-types';
10
- import {
11
- ApolloError,
12
- AuthenticationError,
13
- ForbiddenError,
14
- } from 'apollo-server-errors';
15
1
  import { isObject } from '../utilities/predicates';
16
2
  import { GraphQLDataSource, GraphQLDataSourceProcessOptions, GraphQLDataSourceRequestKind } from './types';
17
3
  import { createHash } from '@apollo/utils.createhash';
@@ -19,6 +5,8 @@ import { parseCacheControlHeader } from './parseCacheControlHeader';
19
5
  import fetcher from 'make-fetch-happen';
20
6
  import { Headers as NodeFetchHeaders, Request as NodeFetchRequest } from 'node-fetch';
21
7
  import { Fetcher, FetcherRequestInit, FetcherResponse } from '@apollo/utils.fetcher';
8
+ import { GraphQLError, GraphQLErrorExtensions } from 'graphql';
9
+ import { GatewayCacheHint, GatewayCachePolicy, GatewayGraphQLRequest, GatewayGraphQLRequestContext, GatewayGraphQLResponse } from '@apollo/server-gateway-interface';
22
10
 
23
11
  export class RemoteGraphQLDataSource<
24
12
  TContext extends Record<string, any> = Record<string, any>,
@@ -77,7 +65,7 @@ export class RemoteGraphQLDataSource<
77
65
 
78
66
  async process(
79
67
  options: GraphQLDataSourceProcessOptions<TContext>,
80
- ): Promise<GraphQLResponse> {
68
+ ): Promise<GatewayGraphQLResponse> {
81
69
  const { request, context: originalContext } = options;
82
70
  // Deal with a bit of a hairy situation in typings: when doing health checks
83
71
  // and schema checks we always pass in `{}` as the context even though it's
@@ -161,7 +149,7 @@ export class RemoteGraphQLDataSource<
161
149
  // If APQ was enabled, we'll run the same request again, but add in the
162
150
  // previously omitted `query`. If APQ was NOT enabled, this is the first
163
151
  // request (non-APQ, all the way).
164
- const requestWithQuery: GraphQLRequest = {
152
+ const requestWithQuery: GatewayGraphQLRequest = {
165
153
  query,
166
154
  ...requestWithoutQuery,
167
155
  };
@@ -175,9 +163,9 @@ export class RemoteGraphQLDataSource<
175
163
  }
176
164
 
177
165
  private async sendRequest(
178
- request: GraphQLRequest,
166
+ request: GatewayGraphQLRequest,
179
167
  context: TContext,
180
- ): Promise<GraphQLResponse> {
168
+ ): Promise<GatewayGraphQLResponse> {
181
169
  // This would represent an internal programming error since this shouldn't
182
170
  // be possible in the way that this method is invoked right now.
183
171
  if (!request.http) {
@@ -230,7 +218,7 @@ export class RemoteGraphQLDataSource<
230
218
 
231
219
  public willSendRequest?(
232
220
  options: GraphQLDataSourceProcessOptions<TContext>,
233
- ): ValueOrPromise<void>;
221
+ ): void | Promise<void>;
234
222
 
235
223
  private async respond({
236
224
  response,
@@ -238,11 +226,11 @@ export class RemoteGraphQLDataSource<
238
226
  context,
239
227
  overallCachePolicy,
240
228
  }: {
241
- response: GraphQLResponse;
242
- request: GraphQLRequest;
229
+ response: GatewayGraphQLResponse;
230
+ request: GatewayGraphQLRequest;
243
231
  context: TContext;
244
- overallCachePolicy: CachePolicy | null;
245
- }): Promise<GraphQLResponse> {
232
+ overallCachePolicy: GatewayCachePolicy | null;
233
+ }): Promise<GatewayGraphQLResponse> {
246
234
  const processedResponse =
247
235
  typeof this.didReceiveResponse === 'function'
248
236
  ? await this.didReceiveResponse({ response, request, context })
@@ -257,16 +245,16 @@ export class RemoteGraphQLDataSource<
257
245
  // thus the overall response) is uncacheable. (If you don't like this, you
258
246
  // can tweak the `cache-control` header in your `didReceiveResponse`
259
247
  // method.)
260
- const hint: CacheHint = { maxAge: 0 };
248
+ const hint: GatewayCacheHint = { maxAge: 0 };
261
249
  const maxAge = parsed['max-age'];
262
250
  if (typeof maxAge === 'string' && maxAge.match(/^[0-9]+$/)) {
263
251
  hint.maxAge = +maxAge;
264
252
  }
265
253
  if (parsed['private'] === true) {
266
- hint.scope = CacheScope.Private;
254
+ hint.scope = 'PRIVATE';
267
255
  }
268
256
  if (parsed['public'] === true) {
269
- hint.scope = CacheScope.Public;
257
+ hint.scope = 'PUBLIC';
270
258
  }
271
259
  overallCachePolicy.restrict(hint);
272
260
  }
@@ -276,9 +264,9 @@ export class RemoteGraphQLDataSource<
276
264
 
277
265
  public didReceiveResponse?(
278
266
  requestContext: Required<
279
- Pick<GraphQLRequestContext<TContext>, 'request' | 'response' | 'context'>
267
+ Pick<GatewayGraphQLRequestContext<TContext>, 'request' | 'response' | 'context'>
280
268
  >,
281
- ): ValueOrPromise<GraphQLResponse>;
269
+ ): GatewayGraphQLResponse | Promise<GatewayGraphQLResponse>;
282
270
 
283
271
  public didEncounterError(
284
272
  error: Error,
@@ -303,28 +291,36 @@ export class RemoteGraphQLDataSource<
303
291
  }
304
292
 
305
293
  public async errorFromResponse(response: FetcherResponse) {
306
- const message = `${response.status}: ${response.statusText}`;
307
-
308
- let error: ApolloError;
309
- if (response.status === 401) {
310
- error = new AuthenticationError(message);
311
- } else if (response.status === 403) {
312
- error = new ForbiddenError(message);
313
- } else {
314
- error = new ApolloError(message);
315
- }
316
-
317
294
  const body = await this.parseBody(response);
318
295
 
319
- Object.assign(error.extensions, {
296
+ const extensions: GraphQLErrorExtensions = {
320
297
  response: {
321
298
  url: response.url,
322
299
  status: response.status,
323
300
  statusText: response.statusText,
324
301
  body,
325
302
  },
326
- });
303
+ };
304
+
305
+ if (response.status === 401) {
306
+ extensions.code = 'UNAUTHENTICATED';
307
+ } else if (response.status === 403) {
308
+ extensions.code = 'FORBIDDEN';
309
+ }
327
310
 
328
- return error;
311
+ // Note: gateway 0.x still supports graphql-js v15.8, which does
312
+ // not have the options-based GraphQLError constructor. Note that
313
+ // the constructor used here is dropped in graphql-js v17, so this
314
+ // will have to be adjusted if we try to make gateway 0.x support
315
+ // graphql-js v17.
316
+ return new GraphQLError(
317
+ `${response.status}: ${response.statusText}`,
318
+ null,
319
+ null,
320
+ null,
321
+ null,
322
+ null,
323
+ extensions,
324
+ );
329
325
  }
330
326
  }
@@ -2,8 +2,8 @@ import { LocalGraphQLDataSource } from '../LocalGraphQLDataSource';
2
2
  import { buildSubgraphSchema } from '@apollo/subgraph';
3
3
  import gql from 'graphql-tag';
4
4
  import { GraphQLResolverMap } from '@apollo/subgraph/src/schema-helper';
5
- import { GraphQLRequestContext } from 'apollo-server-types';
6
5
  import { GraphQLDataSourceRequestKind } from '../types';
6
+ import { GatewayGraphQLRequestContext } from '@apollo/server-gateway-interface';
7
7
 
8
8
  describe('constructing requests', () => {
9
9
  it('accepts context', async () => {
@@ -42,7 +42,7 @@ describe('constructing requests', () => {
42
42
  },
43
43
  incomingRequestContext: {
44
44
  context: { userId: 2 },
45
- } as GraphQLRequestContext<{userId: number}>,
45
+ } as GatewayGraphQLRequestContext<{userId: number}>,
46
46
  context: { userId: 2 },
47
47
  });
48
48
 
@@ -1,15 +1,10 @@
1
- import {
2
- ApolloError,
3
- AuthenticationError,
4
- ForbiddenError,
5
- } from 'apollo-server-errors';
6
-
7
1
  import { RemoteGraphQLDataSource } from '../RemoteGraphQLDataSource';
8
2
  import { Response, Headers } from 'node-fetch';
9
- import { GraphQLRequestContext } from 'apollo-server-types';
10
3
  import { GraphQLDataSourceRequestKind } from '../types';
11
4
  import { nockBeforeEach, nockAfterEach } from '../../__tests__/nockAssertions';
12
5
  import nock from 'nock';
6
+ import { GraphQLError } from 'graphql';
7
+ import { GatewayGraphQLRequestContext } from '@apollo/server-gateway-interface';
13
8
 
14
9
  beforeEach(nockBeforeEach);
15
10
  afterEach(nockAfterEach);
@@ -322,7 +317,7 @@ describe('didReceiveResponse', () => {
322
317
  response,
323
318
  }: Required<
324
319
  Pick<
325
- GraphQLRequestContext<MyContext>,
320
+ GatewayGraphQLRequestContext<MyContext>,
326
321
  'request' | 'response' | 'context'
327
322
  >
328
323
  >) {
@@ -367,7 +362,7 @@ describe('didReceiveResponse', () => {
367
362
  response,
368
363
  }: Required<
369
364
  Pick<
370
- GraphQLRequestContext<MyContext>,
365
+ GatewayGraphQLRequestContext<MyContext>,
371
366
  'request' | 'response' | 'context'
372
367
  >
373
368
  >) {
@@ -403,7 +398,7 @@ describe('didReceiveResponse', () => {
403
398
  response,
404
399
  }: Required<
405
400
  Pick<
406
- GraphQLRequestContext<MyContext>,
401
+ GatewayGraphQLRequestContext<MyContext>,
407
402
  'request' | 'response' | 'context'
408
403
  >
409
404
  >) {
@@ -457,11 +452,11 @@ describe('didEncounterError', () => {
457
452
  },
458
453
  incomingRequestContext: {
459
454
  context,
460
- } as GraphQLRequestContext<MyContext>,
455
+ } as GatewayGraphQLRequestContext<MyContext>,
461
456
  context,
462
457
  });
463
458
 
464
- await expect(result).rejects.toThrow(AuthenticationError);
459
+ await expect(result).rejects.toThrow(GraphQLError);
465
460
  expect(context).toMatchObject({
466
461
  timingData: [{ time: 1616446845234 }],
467
462
  });
@@ -469,7 +464,7 @@ describe('didEncounterError', () => {
469
464
  });
470
465
 
471
466
  describe('error handling', () => {
472
- it('throws an AuthenticationError when the response status is 401', async () => {
467
+ it('throws error with code UNAUTHENTICATED when the response status is 401', async () => {
473
468
  const DataSource = new RemoteGraphQLDataSource({
474
469
  url: 'https://api.example.com/foo',
475
470
  });
@@ -480,7 +475,7 @@ describe('error handling', () => {
480
475
  ...defaultProcessOptions,
481
476
  request: { query: '{ me { name } }' },
482
477
  });
483
- await expect(result).rejects.toThrow(AuthenticationError);
478
+ await expect(result).rejects.toThrow(GraphQLError);
484
479
  await expect(result).rejects.toMatchObject({
485
480
  extensions: {
486
481
  code: 'UNAUTHENTICATED',
@@ -492,7 +487,7 @@ describe('error handling', () => {
492
487
  });
493
488
  });
494
489
 
495
- it('throws a ForbiddenError when the response status is 403', async () => {
490
+ it('throws an error with code FORBIDDEN when the response status is 403', async () => {
496
491
  const DataSource = new RemoteGraphQLDataSource({
497
492
  url: 'https://api.example.com/foo',
498
493
  });
@@ -503,7 +498,7 @@ describe('error handling', () => {
503
498
  ...defaultProcessOptions,
504
499
  request: { query: '{ me { name } }' },
505
500
  });
506
- await expect(result).rejects.toThrow(ForbiddenError);
501
+ await expect(result).rejects.toThrow(GraphQLError);
507
502
  await expect(result).rejects.toMatchObject({
508
503
  extensions: {
509
504
  code: 'FORBIDDEN',
@@ -515,7 +510,7 @@ describe('error handling', () => {
515
510
  });
516
511
  });
517
512
 
518
- it('throws an ApolloError when the response status is 500', async () => {
513
+ it('throws a GraphQLError when the response status is 500', async () => {
519
514
  const DataSource = new RemoteGraphQLDataSource({
520
515
  url: 'https://api.example.com/foo',
521
516
  });
@@ -526,7 +521,7 @@ describe('error handling', () => {
526
521
  ...defaultProcessOptions,
527
522
  request: { query: '{ me { name } }' },
528
523
  });
529
- await expect(result).rejects.toThrow(ApolloError);
524
+ await expect(result).rejects.toThrow(GraphQLError);
530
525
  await expect(result).rejects.toMatchObject({
531
526
  extensions: {
532
527
  response: {
@@ -560,7 +555,7 @@ describe('error handling', () => {
560
555
  ...defaultProcessOptions,
561
556
  request: { query: '{ me { name } }' },
562
557
  });
563
- await expect(result).rejects.toThrow(ApolloError);
558
+ await expect(result).rejects.toThrow(GraphQLError);
564
559
  await expect(result).rejects.toMatchObject({
565
560
  extensions: {
566
561
  response: {
@@ -1,11 +1,11 @@
1
- import { GraphQLResponse, GraphQLRequestContext } from 'apollo-server-types';
1
+ import { GatewayGraphQLResponse, GatewayGraphQLRequestContext } from '@apollo/server-gateway-interface';
2
2
 
3
3
  export interface GraphQLDataSource<
4
4
  TContext extends Record<string, any> = Record<string, any>,
5
5
  > {
6
6
  process(
7
7
  options: GraphQLDataSourceProcessOptions<TContext>,
8
- ): Promise<GraphQLResponse>;
8
+ ): Promise<GatewayGraphQLResponse>;
9
9
  }
10
10
 
11
11
  export enum GraphQLDataSourceRequestKind {
@@ -20,7 +20,7 @@ export type GraphQLDataSourceProcessOptions<
20
20
  /**
21
21
  * The request to send to the subgraph.
22
22
  */
23
- request: GraphQLRequestContext<TContext>['request'];
23
+ request: GatewayGraphQLRequestContext<TContext>['request'];
24
24
  } & (
25
25
  | {
26
26
  kind: GraphQLDataSourceRequestKind.INCOMING_OPERATION;
@@ -28,8 +28,15 @@ export type GraphQLDataSourceProcessOptions<
28
28
  * The GraphQLRequestContext for the operation received by the gateway, or
29
29
  * one of the strings if this operation is generated by the gateway without an
30
30
  * incoming request.
31
+ *
32
+ * For backwards compatibility with Apollo Server 2, `overallCachePolicy` needs
33
+ * to be treated as optional.
31
34
  */
32
- incomingRequestContext: GraphQLRequestContext<TContext>;
35
+ incomingRequestContext: Omit<
36
+ GatewayGraphQLRequestContext<TContext>,
37
+ 'overallCachePolicy'
38
+ > &
39
+ Pick<Partial<GatewayGraphQLRequestContext<TContext>>, 'overallCachePolicy'>;
33
40
  /**
34
41
  * Equivalent to incomingRequestContext.context (provided here for
35
42
  * backwards compatibility): the object created by the Apollo Server
@@ -38,7 +45,7 @@ export type GraphQLDataSourceProcessOptions<
38
45
  * @deprecated Use `incomingRequestContext.context` instead (after
39
46
  * checking `kind`).
40
47
  */
41
- context: GraphQLRequestContext<TContext>['context'];
48
+ context: GatewayGraphQLRequestContext<TContext>['context'];
42
49
  }
43
50
  | {
44
51
  kind:
@@ -1,8 +1,3 @@
1
- import {
2
- GraphQLExecutionResult,
3
- GraphQLRequestContext,
4
- VariableValues,
5
- } from 'apollo-server-types';
6
1
  import { Headers } from 'node-fetch';
7
2
  import {
8
3
  execute,
@@ -34,6 +29,7 @@ import { deepMerge } from './utilities/deepMerge';
34
29
  import { isNotNullOrUndefined } from './utilities/array';
35
30
  import { SpanStatusCode } from "@opentelemetry/api";
36
31
  import { OpenTelemetrySpanNames, tracer } from "./utilities/opentelemetry";
32
+ import { GatewayGraphQLRequestContext, GatewayExecutionResult } from '@apollo/server-gateway-interface';
37
33
 
38
34
  export type ServiceMap = {
39
35
  [serviceName: string]: GraphQLDataSource;
@@ -41,20 +37,20 @@ export type ServiceMap = {
41
37
 
42
38
  type ResultMap = Record<string, any>;
43
39
 
44
- interface ExecutionContext<TContext> {
40
+ interface ExecutionContext {
45
41
  queryPlan: QueryPlan;
46
42
  operationContext: OperationContext;
47
43
  serviceMap: ServiceMap;
48
- requestContext: GraphQLRequestContext<TContext>;
44
+ requestContext: GatewayGraphQLRequestContext;
49
45
  errors: GraphQLError[];
50
46
  }
51
47
 
52
- export async function executeQueryPlan<TContext>(
48
+ export async function executeQueryPlan(
53
49
  queryPlan: QueryPlan,
54
50
  serviceMap: ServiceMap,
55
- requestContext: GraphQLRequestContext<TContext>,
51
+ requestContext: GatewayGraphQLRequestContext,
56
52
  operationContext: OperationContext,
57
- ): Promise<GraphQLExecutionResult> {
53
+ ): Promise<GatewayExecutionResult> {
58
54
 
59
55
  const logger = requestContext.logger || console;
60
56
 
@@ -62,7 +58,7 @@ export async function executeQueryPlan<TContext>(
62
58
  try {
63
59
  const errors: GraphQLError[] = [];
64
60
 
65
- const context: ExecutionContext<TContext> = {
61
+ const context: ExecutionContext = {
66
62
  queryPlan,
67
63
  operationContext,
68
64
  serviceMap,
@@ -171,8 +167,8 @@ export async function executeQueryPlan<TContext>(
171
167
  // we're going to ignore it, because it makes the code much simpler and more
172
168
  // typesafe. However, it doesn't actually ask for traces from the backend
173
169
  // service unless we are capturing traces for Studio.
174
- async function executeNode<TContext>(
175
- context: ExecutionContext<TContext>,
170
+ async function executeNode(
171
+ context: ExecutionContext,
176
172
  node: PlanNode,
177
173
  results: ResultMap | ResultMap[],
178
174
  path: ResponsePath,
@@ -261,7 +257,7 @@ async function executeNode<TContext>(
261
257
 
262
258
  export function shouldSkipFetchNode(
263
259
  node: FetchNode,
264
- variables: VariableValues = {},
260
+ variables: Record<string, any> = {},
265
261
  ) {
266
262
  if (!node.inclusionConditions) return false;
267
263
 
@@ -284,8 +280,8 @@ export function shouldSkipFetchNode(
284
280
  });
285
281
  }
286
282
 
287
- async function executeFetch<TContext>(
288
- context: ExecutionContext<TContext>,
283
+ async function executeFetch(
284
+ context: ExecutionContext,
289
285
  fetch: FetchNode,
290
286
  results: ResultMap | (ResultMap | null | undefined)[],
291
287
  _path: ResponsePath,
@@ -404,7 +400,7 @@ async function executeFetch<TContext>(
404
400
  }
405
401
  });
406
402
  async function sendOperation(
407
- context: ExecutionContext<TContext>,
403
+ context: ExecutionContext,
408
404
  source: string,
409
405
  variables: Record<string, any>,
410
406
  operationName: string | undefined,