Skip to content

Commit

Permalink
feat(federation): graphql gateway module
Browse files Browse the repository at this point in the history
  • Loading branch information
marcus-sa authored and Rick Dutour Geerling committed Jan 20, 2020
1 parent b090702 commit ded92ce
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 0 deletions.
88 changes: 88 additions & 0 deletions lib/graphql-gateway.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { DynamicModule, Inject, Module, OnModuleInit, Optional } from '@nestjs/common';
import { ApolloServer } from 'apollo-server-express';
import { HttpAdapterHost } from '@nestjs/core';
import { GRAPHQL_GATEWAY_BUILD_SERVICE, GRAPHQL_GATEWAY_MODULE_OPTIONS } from './graphql.constants';
import { GatewayBuildService, GatewayModuleOptions } from './interfaces';
import { loadPackage } from '@nestjs/common/utils/load-package.util';

@Module({})
export class GraphQLGatewayModule implements OnModuleInit {
private apolloServer: ApolloServer;

constructor(
@Optional()
private readonly httpAdapterHost: HttpAdapterHost,
@Optional() @Inject(GRAPHQL_GATEWAY_BUILD_SERVICE)
private readonly buildService: GatewayBuildService,
@Inject(GRAPHQL_GATEWAY_MODULE_OPTIONS)
private readonly options: GatewayModuleOptions,
) {}

static forRoot(options: GatewayModuleOptions): DynamicModule {
return {
module: GraphQLGatewayModule,
providers: [
{
provide: GRAPHQL_GATEWAY_MODULE_OPTIONS,
useValue: options,
},
],
};
}

async onModuleInit() {
if (!this.httpAdapterHost) return;
const { httpAdapter } = this.httpAdapterHost;

if (!httpAdapter) return;

const { ApolloGateway } = loadPackage('@apollo/gateway', 'ApolloGateway');
const app = httpAdapter.getInstance();

const {
options: {
__exposeQueryPlanExperimental,
debug,
serviceList,
path,
disableHealthCheck,
onHealthCheck,
cors,
bodyParserConfig,
installSubscriptionHandlers,
},
buildService,
} = this;

const gateway = new ApolloGateway({
__exposeQueryPlanExperimental,
debug,
serviceList,
buildService,
});

const { schema, executor } = await gateway.load();

this.apolloServer = new ApolloServer({
executor,
schema,
});

this.apolloServer.applyMiddleware({
app,
path,
disableHealthCheck,
onHealthCheck,
cors,
bodyParserConfig,
});

if (installSubscriptionHandlers) {
// TL;DR <https://github.com/apollographql/apollo-server/issues/2776>
throw new Error('No support for subscriptions yet when using Apollo Federation');
/*this.apolloServer.installSubscriptionHandlers(
httpAdapter.getHttpServer(),
);*/
}
}
}
3 changes: 3 additions & 0 deletions lib/graphql.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export const SCALAR_TYPE_METADATA = 'graphql:scalar_type';
export const PARAM_ARGS_METADATA = '__routeArguments__';
export const SUBSCRIPTION_OPTIONS_METADATA = 'graphql:subscription_options;';

export const GRAPHQL_GATEWAY_MODULE_OPTIONS = 'graphql:gateway_module_options';
export const GRAPHQL_GATEWAY_BUILD_SERVICE = 'graphql:gateway_build_service';

export const FIELD_TYPENAME = '__resolveType';
export const GRAPHQL_MODULE_OPTIONS = 'GqlModuleOptions';
export const GRAPHQL_MODULE_ID = 'GqlModuleId';
Expand Down
1 change: 1 addition & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './interfaces';
export * from './services/gql-arguments-host';
export * from './services/gql-execution-context';
export * from './tokens';
export * from './graphql-gateway.module';

0 comments on commit ded92ce

Please sign in to comment.