Skip to content

Commit 0b9cb93

Browse files
feat: onSchema will be used new hook implementation
1 parent bc18709 commit 0b9cb93

File tree

3 files changed

+49
-5
lines changed

3 files changed

+49
-5
lines changed

.changeset/metal-colts-begin.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@apollo/gateway": minor
3+
---
4+
5+
feat: onSchema will be used new hook implementation

gateway-js/src/__tests__/gateway/lifecycle-hooks.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ describe('lifecycle hooks', () => {
104104
});
105105

106106
const mockDidUpdate = jest.fn();
107+
const mockOnSchemaWillBeUsed = jest.fn();
107108

108109
const gateway = new ApolloGateway({
109110
experimental_updateServiceDefinitions: mockUpdate,
@@ -113,6 +114,7 @@ describe('lifecycle hooks', () => {
113114
// for testing purposes, a short pollInterval is ideal so we'll override here
114115
gateway['pollIntervalInMs'] = 100;
115116

117+
gateway.onSchemaWillBeUsed(mockOnSchemaWillBeUsed);
116118
const schemaChangeBlocker1 = resolvable();
117119
const schemaChangeBlocker2 = resolvable();
118120

@@ -154,6 +156,7 @@ describe('lifecycle hooks', () => {
154156
// second call should have previous info in the second arg
155157
expect(secondCall[1]!.compositionId).toEqual(expectedFirstId);
156158

159+
expect(mockOnSchemaWillBeUsed).toHaveBeenCalledTimes(2);
157160
await gateway.stop();
158161
});
159162

gateway-js/src/index.ts

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { deprecate } from 'util';
22
import { createHash } from '@apollo/utils.createhash';
33
import type { Logger } from '@apollo/utils.logger';
4-
import { QueryPlanCache } from '@apollo/query-planner'
4+
import { QueryPlanCache } from '@apollo/query-planner';
55
import { InMemoryLRUCache } from '@apollo/utils.keyvaluecache';
66
import {
77
GraphQLSchema,
@@ -47,7 +47,7 @@ import {
4747
requestContextSpanAttributes,
4848
operationContextSpanAttributes,
4949
recordExceptions,
50-
OpenTelemetryAttributeNames
50+
OpenTelemetryAttributeNames,
5151
} from './utilities/opentelemetry';
5252
import { addExtensions } from './schema-helper/addExtensions';
5353
import {
@@ -141,6 +141,12 @@ export class ApolloGateway implements GatewayInterface {
141141
coreSupergraphSdl: string;
142142
}) => void
143143
>();
144+
private onSchemaWillBeUsedListeners = new Set<
145+
(schemaContext: {
146+
apiSchema: GraphQLSchema;
147+
coreSupergraphSdl: string;
148+
}) => void
149+
>();
144150
private warnedStates: WarnedStates = Object.create(null);
145151
private queryPlanner?: QueryPlanner;
146152
private supergraphSdl?: string;
@@ -198,8 +204,8 @@ export class ApolloGateway implements GatewayInterface {
198204
}
199205

200206
private initQueryPlanStore(approximateQueryPlanStoreMiB?: number) {
201-
if(this.config.queryPlannerConfig?.cache){
202-
return this.config.queryPlannerConfig?.cache
207+
if (this.config.queryPlannerConfig?.cache) {
208+
return this.config.queryPlannerConfig?.cache;
203209
}
204210
// Create ~about~ a 30MiB InMemoryLRUCache (or 50MiB if the full operation ASTs are
205211
// enabled in query plans as this requires plans to use more memory). This is
@@ -569,6 +575,23 @@ export class ApolloGateway implements GatewayInterface {
569575
legacyDontNotifyOnSchemaChangeListeners: boolean = false,
570576
): void {
571577
this.queryPlanStore.clear();
578+
579+
// Notify before use of new schema
580+
this.onSchemaWillBeUsedListeners.forEach((listener) => {
581+
try {
582+
listener({
583+
apiSchema: this.schema!,
584+
coreSupergraphSdl: supergraphSdl,
585+
});
586+
} catch (e) {
587+
this.logger.error(
588+
"An error was thrown from an 'onSchemaWillBeUsed' listener. " +
589+
'The schema will still update: ' +
590+
((e && e.message) || e),
591+
);
592+
}
593+
});
594+
572595
this.apiSchema = supergraph.apiSchema();
573596
this.schema = addExtensions(this.apiSchema.toGraphQLJSSchema());
574597

@@ -681,6 +704,19 @@ export class ApolloGateway implements GatewayInterface {
681704
};
682705
}
683706

707+
public onSchemaWillBeUsed(
708+
callback: (schemaContext: {
709+
apiSchema: GraphQLSchema;
710+
coreSupergraphSdl: string;
711+
}) => void,
712+
): GatewayUnsubscriber {
713+
this.onSchemaWillBeUsedListeners.add(callback);
714+
715+
return () => {
716+
this.onSchemaWillBeUsedListeners.delete(callback);
717+
};
718+
}
719+
684720
private getOrCreateDataSource(
685721
serviceDef: ServiceEndpointDefinition,
686722
): GraphQLDataSource {
@@ -850,7 +886,7 @@ export class ApolloGateway implements GatewayInterface {
850886
operationContext,
851887
this.supergraphSchema!,
852888
this.apiSchema!,
853-
this.config.telemetry
889+
this.config.telemetry,
854890
);
855891

856892
const shouldShowQueryPlan =

0 commit comments

Comments
 (0)