Skip to content

Commit a198c6a

Browse files
committed
refactor: decouple schema generation from driver start
1 parent 670b486 commit a198c6a

File tree

10 files changed

+69
-63
lines changed

10 files changed

+69
-63
lines changed

packages/apollo/lib/drivers/apollo-federation.driver.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
22
import { loadPackage } from '@nestjs/common/utils/load-package.util';
33
import { ModulesContainer } from '@nestjs/core';
44
import { extend, GraphQLFederationFactory } from '@nestjs/graphql';
5+
import { GraphQLSchema } from 'graphql';
56
import { ApolloDriverConfig } from '../interfaces';
67
import { PluginsExplorerService } from '../services/plugins-explorer.service';
78
import { ApolloBaseDriver } from './apollo-base.driver';
@@ -18,16 +19,17 @@ export class ApolloFederationDriver extends ApolloBaseDriver {
1819
this.pluginsExplorerService = new PluginsExplorerService(modulesContainer);
1920
}
2021

22+
async generateSchema(options: ApolloDriverConfig): Promise<GraphQLSchema> {
23+
return await this.graphqlFederationFactory.mergeWithSchema(options);
24+
}
25+
2126
public async start(options: ApolloDriverConfig): Promise<void> {
2227
options.plugins = extend(
2328
options.plugins || [],
2429
this.pluginsExplorerService.explore(options),
2530
);
2631

27-
const adapterOptions = await this.graphqlFederationFactory.mergeWithSchema(
28-
options,
29-
);
30-
await this.runExecutorFactoryIfPresent(adapterOptions);
32+
await this.runExecutorFactoryIfPresent(options);
3133

3234
if (options.definitions && options.definitions.path) {
3335
const { printSubgraphSchema } = loadPackage(
@@ -36,12 +38,12 @@ export class ApolloFederationDriver extends ApolloBaseDriver {
3638
() => require('@apollo/subgraph'),
3739
);
3840
await this.graphQlFactory.generateDefinitions(
39-
printSubgraphSchema(adapterOptions.schema),
41+
printSubgraphSchema(options.schema),
4042
options,
4143
);
4244
}
4345

44-
await super.start(adapterOptions);
46+
await super.start(options);
4547

4648
if (options.installSubscriptionHandlers || options.subscriptions) {
4749
// TL;DR <https://github.com/apollographql/apollo-server/issues/2776>

packages/apollo/lib/drivers/apollo-gateway.driver.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
22
import { loadPackage } from '@nestjs/common/utils/load-package.util';
33
import { ModulesContainer } from '@nestjs/core';
44
import { extend } from '@nestjs/graphql';
5+
import { GraphQLSchema } from 'graphql';
56
import { ApolloGatewayDriverConfig } from '../interfaces';
67
import { PluginsExplorerService } from '../services/plugins-explorer.service';
78
import { ApolloBaseDriver } from './apollo-base.driver';
@@ -15,6 +16,12 @@ export class ApolloGatewayDriver extends ApolloBaseDriver<ApolloGatewayDriverCon
1516
this.pluginsExplorerService = new PluginsExplorerService(modulesContainer);
1617
}
1718

19+
public async generateSchema(
20+
options: ApolloGatewayDriverConfig,
21+
): Promise<GraphQLSchema> {
22+
return new GraphQLSchema({});
23+
}
24+
1825
public async start(options: ApolloGatewayDriverConfig): Promise<void> {
1926
options.server.plugins = extend(
2027
options.server.plugins || [],

packages/apollo/lib/drivers/apollo.driver.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,12 @@ export class ApolloDriver extends ApolloBaseDriver {
2020
this.pluginsExplorerService = new PluginsExplorerService(modulesContainer);
2121
}
2222

23-
public async start(apolloOptions: ApolloDriverConfig) {
24-
apolloOptions.plugins = extend(
25-
apolloOptions.plugins || [],
26-
this.pluginsExplorerService.explore(apolloOptions),
23+
public async start(options: ApolloDriverConfig) {
24+
options.plugins = extend(
25+
options.plugins || [],
26+
this.pluginsExplorerService.explore(options),
2727
);
2828

29-
const options =
30-
await this.graphQlFactory.mergeWithSchema<ApolloDriverConfig>(
31-
apolloOptions,
32-
);
33-
3429
if (options.definitions && options.definitions.path) {
3530
await this.graphQlFactory.generateDefinitions(
3631
printSchema(options.schema),

packages/graphql/lib/drivers/abstract-graphql.driver.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Inject } from '@nestjs/common';
22
import { ApplicationConfig, HttpAdapterHost } from '@nestjs/core';
3+
import { GraphQLSchema } from 'graphql';
34
import { GraphQLFactory } from '../graphql.factory';
45
import { GqlModuleOptions, GraphQLDriver } from '../interfaces';
56
import { normalizeRoutePath } from '../utils';
@@ -36,6 +37,10 @@ export abstract class AbstractGraphQLDriver<
3637
return clonedOptions;
3738
}
3839

40+
public async generateSchema(options: TOptions): Promise<GraphQLSchema> {
41+
return await this.graphQlFactory.mergeWithSchema(options);
42+
}
43+
3944
public subscriptionWithFilter(
4045
instanceRef: unknown,
4146
filterFn: (

packages/graphql/lib/federation/graphql-federation.factory.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import {
2525
import { gql } from 'graphql-tag';
2626
import { forEach, isEmpty } from 'lodash';
2727
import { GraphQLSchemaBuilder } from '../graphql-schema.builder';
28-
import { GraphQLSchemaHost } from '../graphql-schema.host';
2928
import {
3029
AutoSchemaFileValue,
3130
BuildFederatedSchemaOptions,
@@ -46,7 +45,6 @@ export class GraphQLFederationFactory {
4645
private readonly resolversExplorerService: ResolversExplorerService,
4746
private readonly scalarsExplorerService: ScalarsExplorerService,
4847
private readonly gqlSchemaBuilder: GraphQLSchemaBuilder,
49-
private readonly gqlSchemaHost: GraphQLSchemaHost,
5048
private readonly typeDefsDecoratorFactory: TypeDefsDecoratorFactory,
5149
) {}
5250

@@ -55,9 +53,9 @@ export class GraphQLFederationFactory {
5553
buildFederatedSchema?: (
5654
options: BuildFederatedSchemaOptions,
5755
) => GraphQLSchema,
58-
): Promise<T> {
59-
const transformSchema = async (schema: GraphQLSchema) =>
60-
options.transformSchema ? options.transformSchema(schema) : schema;
56+
): Promise<GraphQLSchema> {
57+
const transformSchema =
58+
options.transformSchema ?? ((schema: GraphQLSchema) => schema);
6159

6260
let schema: GraphQLSchema;
6361
if (options.autoSchemaFile) {
@@ -68,13 +66,7 @@ export class GraphQLFederationFactory {
6866
schema = this.buildSchemaFromTypeDefs(options);
6967
}
7068

71-
this.gqlSchemaHost.schema = schema;
72-
73-
return {
74-
...options,
75-
schema: await transformSchema(schema),
76-
typeDefs: undefined,
77-
};
69+
return await transformSchema(schema);
7870
}
7971

8072
private buildSchemaFromTypeDefs<T extends GqlModuleOptions>(options: T) {

packages/graphql/lib/graphql.factory.ts

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import {
1616
GraphQLAstExplorer,
1717
} from './graphql-ast.explorer';
1818
import { GraphQLSchemaBuilder } from './graphql-schema.builder';
19-
import { GraphQLSchemaHost } from './graphql-schema.host';
2019
import { GqlModuleOptions } from './interfaces';
2120
import { ResolversExplorerService, ScalarsExplorerService } from './services';
2221
import { extend, removeTempField } from './utils';
@@ -28,12 +27,11 @@ export class GraphQLFactory {
2827
private readonly scalarsExplorerService: ScalarsExplorerService,
2928
private readonly graphqlAstExplorer: GraphQLAstExplorer,
3029
private readonly gqlSchemaBuilder: GraphQLSchemaBuilder,
31-
private readonly gqlSchemaHost: GraphQLSchemaHost,
3230
) {}
3331

3432
async mergeWithSchema<T extends GqlModuleOptions>(
3533
options: T = { typeDefs: [] } as T,
36-
): Promise<T> {
34+
): Promise<GraphQLSchema> {
3735
const resolvers = this.resolversExplorerService.explore();
3836
const typesResolvers = extend(
3937
this.scalarsExplorerService.explore(),
@@ -76,22 +74,11 @@ export class GraphQLFactory {
7674
schema = new GraphQLSchema(schemaConfig);
7775
schema = await transformSchema(schema);
7876
schema = options.sortSchema ? lexicographicSortSchema(schema) : schema;
79-
this.gqlSchemaHost.schema = schema;
80-
81-
return {
82-
...options,
83-
typeDefs: undefined,
84-
schema,
85-
};
77+
return schema;
8678
}
8779
if (isEmpty(options.typeDefs)) {
8880
const schema = await transformSchema(options.schema);
89-
this.gqlSchemaHost.schema = schema;
90-
return {
91-
...options,
92-
typeDefs: undefined,
93-
schema,
94-
};
81+
return schema;
9582
}
9683
const executableSchema = makeExecutableSchema({
9784
resolvers: extend(typesResolvers, options.resolvers),
@@ -110,13 +97,7 @@ export class GraphQLFactory {
11097
removeTempField(schema);
11198
schema = await transformSchema(schema);
11299
schema = options.sortSchema ? lexicographicSortSchema(schema) : schema;
113-
this.gqlSchemaHost.schema = schema;
114-
115-
return {
116-
...options,
117-
typeDefs: undefined,
118-
schema,
119-
};
100+
return schema;
120101
}
121102

122103
overrideOrExtendResolvers(

packages/graphql/lib/graphql.module.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export class GraphQLModule<
6464
@Inject(GRAPHQL_MODULE_OPTIONS) private readonly options: GqlModuleOptions,
6565
private readonly _graphQlAdapter: AbstractGraphQLDriver,
6666
private readonly graphQlTypesLoader: GraphQLTypesLoader,
67+
private readonly gqlSchemaHost: GraphQLSchemaHost,
6768
) {}
6869

6970
async onModuleDestroy() {
@@ -158,10 +159,20 @@ export class GraphQLModule<
158159
(await this.graphQlTypesLoader.mergeTypesByPaths(typePaths)) || [];
159160

160161
const mergedTypeDefs = extend(typeDefs, options.typeDefs);
161-
await this._graphQlAdapter.start({
162+
163+
const gqlSchema = await this._graphQlAdapter.generateSchema({
162164
...options,
163165
typeDefs: mergedTypeDefs,
164166
});
167+
this.gqlSchemaHost.schema = gqlSchema;
168+
169+
const completeOptions = {
170+
...options,
171+
schema: gqlSchema,
172+
typeDefs: undefined,
173+
};
174+
175+
await this._graphQlAdapter.start(completeOptions);
165176

166177
if (options.path) {
167178
GraphQLModule.logger.log(

packages/mercurius/lib/drivers/mercurius-federation.driver.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
GraphQLFederationFactory,
55
} from '@nestjs/graphql';
66
import { FastifyInstance, FastifyLoggerInstance } from 'fastify';
7-
import { printSchema } from 'graphql';
7+
import { GraphQLSchema, printSchema } from 'graphql';
88
import { IncomingMessage, Server, ServerResponse } from 'http';
99
import mercurius from 'mercurius';
1010
import { MercuriusDriverConfig } from '../interfaces/mercurius-driver-config.interface';
@@ -28,12 +28,17 @@ export class MercuriusFederationDriver extends AbstractGraphQLDriver<MercuriusDr
2828
return this.httpAdapterHost?.httpAdapter?.getInstance?.();
2929
}
3030

31+
public override async generateSchema(
32+
options: MercuriusDriverConfig,
33+
): Promise<GraphQLSchema> {
34+
return await this.graphqlFederationFactory.mergeWithSchema(
35+
options,
36+
buildMercuriusFederatedSchema,
37+
);
38+
}
39+
3140
public async start(options: MercuriusDriverConfig) {
32-
const { plugins, ...adapterOptions } =
33-
await this.graphqlFederationFactory.mergeWithSchema(
34-
options,
35-
buildMercuriusFederatedSchema,
36-
);
41+
const { plugins, ...adapterOptions } = options;
3742

3843
if (adapterOptions.definitions && adapterOptions.definitions.path) {
3944
await this.graphQlFactory.generateDefinitions(
@@ -55,6 +60,6 @@ export class MercuriusFederationDriver extends AbstractGraphQLDriver<MercuriusDr
5560
await registerMercuriusPlugin(app, plugins);
5661
}
5762

58-
/* eslit-disable-next-line @typescript-eslint/no-empty-function */
63+
/* eslint-disable-next-line @typescript-eslint/no-empty-function */
5964
public async stop(): Promise<void> {}
6065
}

packages/mercurius/lib/drivers/mercurius-gateway.driver.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { AbstractGraphQLDriver } from '@nestjs/graphql';
22
import { FastifyInstance, FastifyLoggerInstance } from 'fastify';
3+
import { GraphQLSchema } from 'graphql';
34
import { IncomingMessage, Server, ServerResponse } from 'http';
45
import mercurius from 'mercurius';
56
import { MercuriusDriverConfig } from '../interfaces/mercurius-driver-config.interface';
@@ -15,6 +16,12 @@ export class MercuriusGatewayDriver extends AbstractGraphQLDriver<MercuriusDrive
1516
return this.httpAdapterHost?.httpAdapter?.getInstance?.();
1617
}
1718

19+
public async generateSchema(
20+
options: MercuriusDriverConfig,
21+
): Promise<GraphQLSchema> {
22+
return new GraphQLSchema({});
23+
}
24+
1825
public async start(options: MercuriusDriverConfig) {
1926
const httpAdapter = this.httpAdapterHost.httpAdapter;
2027
const platformName = httpAdapter.getType();
@@ -23,7 +30,11 @@ export class MercuriusGatewayDriver extends AbstractGraphQLDriver<MercuriusDrive
2330
throw new Error(`No support for current HttpAdapter: ${platformName}`);
2431
}
2532

26-
const { plugins, ...mercuriusOptions } = options;
33+
const {
34+
plugins,
35+
schema: _, // Schema stubbed to be compatible with other drivers, ignore.
36+
...mercuriusOptions
37+
} = options;
2738
const app = httpAdapter.getInstance<FastifyInstance>();
2839
await app.register(mercurius, {
2940
...mercuriusOptions,

packages/mercurius/lib/drivers/mercurius.driver.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ export class MercuriusDriver extends AbstractGraphQLDriver<MercuriusDriverConfig
1818
}
1919

2020
public async start(mercuriusOptions: MercuriusDriverConfig) {
21-
const { plugins, ...options } =
22-
await this.graphQlFactory.mergeWithSchema<MercuriusDriverConfig>(
23-
mercuriusOptions,
24-
);
21+
const { plugins, ...options } = mercuriusOptions;
2522

2623
if (options.definitions && options.definitions.path) {
2724
await this.graphQlFactory.generateDefinitions(

0 commit comments

Comments
 (0)