Skip to content

Commit

Permalink
fix(federation): avoid using transform schema for federation #981
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilmysliwiec committed Jun 24, 2020
1 parent 69b3d78 commit 3358899
Showing 1 changed file with 38 additions and 12 deletions.
50 changes: 38 additions & 12 deletions lib/federation/graphql-federation.factory.ts
@@ -1,7 +1,6 @@
import { Injectable } from '@nestjs/common';
import { loadPackage } from '@nestjs/common/utils/load-package.util';
import { isString } from '@nestjs/common/utils/shared.utils';
import { transformSchema } from 'apollo-graphql';
import { gql } from 'apollo-server-core';
import {
GraphQLAbstractType,
Expand Down Expand Up @@ -135,20 +134,33 @@ export class GraphQLFederationFactory {
executableSchema: GraphQLSchema,
autoGeneratedSchema: GraphQLSchema,
): GraphQLSchema {
return transformSchema(executableSchema, (type) => {
if (isUnionType(type) && type.name !== '_Entity') {
return this.overrideFederatedResolveType(type, autoGeneratedSchema);
// Note: "transformSchema" from "apollo-graphql" cannot be used since it removes directives added by the "buildFederatedSchema" function
// Ref issue: https://github.com/apollographql/apollo-server/issues/4106
for (const [key, type] of Object.entries(executableSchema.getTypeMap())) {
if (this.isIntrospectionType(key)) {
continue;
}
if (isUnionType(type)) {
executableSchema.getTypeMap()[key] = this.overrideFederatedResolveType(
type,
autoGeneratedSchema,
);
} else if (isInterfaceType(type)) {
return this.overrideFederatedResolveType(type, autoGeneratedSchema);
executableSchema.getTypeMap()[key] = this.overrideFederatedResolveType(
type,
autoGeneratedSchema,
);
} else if (isEnumType(type)) {
return autoGeneratedSchema.getType(type.name);
executableSchema.getTypeMap()[key] = autoGeneratedSchema.getType(
type.name,
);
} else if (isInputObjectType(type)) {
const autoGeneratedInputType = autoGeneratedSchema.getType(
type.name,
) as GraphQLInputObjectType;

if (!autoGeneratedInputType) {
return type;
return;
}
const fields = type.getFields();
forEach(fields, (value: GraphQLInputField, key: string) => {
Expand All @@ -160,14 +172,13 @@ export class GraphQLFederationFactory {
value.astNode = field.astNode;
});
type.extensions = autoGeneratedInputType.extensions;
return type;
} else if (isObjectType(type)) {
const autoGeneratedObjectType = autoGeneratedSchema.getType(
type.name,
) as GraphQLObjectType;

if (!autoGeneratedObjectType) {
return type;
return;
}
const fields = type.getFields();
forEach(
Expand All @@ -186,10 +197,25 @@ export class GraphQLFederationFactory {
},
);
type.extensions = autoGeneratedObjectType.extensions;
return type;
}
return type;
});
}
return executableSchema;
}

private isIntrospectionType(typename: string): boolean {
return [
'__Schema',
'__Directive',
'__DirectiveLocation',
'__Type',
'__Field',
'__InputValue',
'__EnumValue',
'__TypeKind',
'_Any',
'_Entity',
'_Service',
].includes(typename);
}

/**
Expand Down

0 comments on commit 3358899

Please sign in to comment.