Skip to content

Commit

Permalink
feat(): override the resolve type of interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilmysliwiec committed May 29, 2020
1 parent f4e99d5 commit af6edc0
Showing 1 changed file with 30 additions and 36 deletions.
66 changes: 30 additions & 36 deletions lib/federation/graphql-federation.factory.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Injectable } from '@nestjs/common';
import { loadPackage } from '@nestjs/common/utils/load-package.util';
import { transformSchema } from 'apollo-graphql';
import { isString } from '@nestjs/common/utils/shared.utils';
import { transformSchema } from 'apollo-graphql';
import { gql } from 'apollo-server-core';
import {
GraphQLAbstractType,
GraphQLField,
GraphQLInputField,
GraphQLInputObjectType,
GraphQLInterfaceType,
GraphQLObjectType,
GraphQLResolveInfo,
GraphQLSchema,
Expand All @@ -18,8 +20,6 @@ import {
isUnionType,
} from 'graphql';
import { mergeSchemas } from 'graphql-tools';
import { PromiseOrValue } from 'graphql/jsutils/PromiseOrValue';
import Maybe from 'graphql/tsutils/Maybe';
import { forEach, isEmpty } from 'lodash';
import { GraphQLSchemaBuilder } from '../graphql-schema.builder';
import { GqlModuleOptions } from '../interfaces';
Expand Down Expand Up @@ -137,13 +137,10 @@ export class GraphQLFederationFactory {
): GraphQLSchema {
return transformSchema(executableSchema, (type) => {
if (isUnionType(type) && type.name !== '_Entity') {
return this.overrideFederatedUnionResolveType(
type,
autoGeneratedSchema,
);
} else if (isEnumType(type)) {
return autoGeneratedSchema.getType(type.name);
return this.overrideFederatedResolveType(type, autoGeneratedSchema);
} else if (isInterfaceType(type)) {
return this.overrideFederatedResolveType(type, autoGeneratedSchema);
} else if (isEnumType(type)) {
return autoGeneratedSchema.getType(type.name);
} else if (isInputObjectType(type)) {
const autoGeneratedInputType = autoGeneratedSchema.getType(
Expand All @@ -154,16 +151,14 @@ export class GraphQLFederationFactory {
return type;
}
const fields = type.getFields();
forEach(
fields,
(value: GraphQLField<unknown, unknown>, key: string) => {
const field = autoGeneratedInputType.getFields()[key];
if (!field) {
return;
}
value.extensions = field.extensions;
},
);
forEach(fields, (value: GraphQLInputField, key: string) => {
const field = autoGeneratedInputType.getFields()[key];
if (!field) {
return;
}
value.extensions = field.extensions;
value.astNode = field.astNode;
});
type.extensions = autoGeneratedInputType.extensions;
return type;
} else if (isObjectType(type)) {
Expand Down Expand Up @@ -198,39 +193,39 @@ export class GraphQLFederationFactory {
}

/**
* Ensures that the resolveType method for unions in the federated schema
* Ensures that the resolveType method for unions and interfaces in the federated schema
* is properly set from the one in the autoGeneratedSchema.
*/
private overrideFederatedUnionResolveType(
unionInFederatedSchema: GraphQLUnionType,
private overrideFederatedResolveType(
typeInFederatedSchema: GraphQLUnionType | GraphQLInterfaceType,
autoGeneratedSchema: GraphQLSchema,
): GraphQLUnionType {
): GraphQLUnionType | GraphQLInterfaceType {
// Get the matching type from the auto generated schema
const autogeneratedUnionType = autoGeneratedSchema.getType(
unionInFederatedSchema.name,
const autoGeneratedType = autoGeneratedSchema.getType(
typeInFederatedSchema.name,
);
// Bail if inconsistent with original schema
if (
!autogeneratedUnionType ||
!(autogeneratedUnionType instanceof GraphQLUnionType) ||
!autogeneratedUnionType.resolveType
!autoGeneratedType ||
!(autoGeneratedType instanceof GraphQLUnionType) ||
!autoGeneratedType.resolveType
) {
return unionInFederatedSchema;
return typeInFederatedSchema;
}

unionInFederatedSchema.resolveType = async (
value: any,
context: any,
typeInFederatedSchema.resolveType = async (
value: unknown,
context: unknown,
info: GraphQLResolveInfo,
abstractType: GraphQLAbstractType,
) => {
const resultFromAutogenSchema = await autogeneratedUnionType.resolveType(
const resultFromAutogenSchema = await autoGeneratedType.resolveType(
value,
context,
info,
abstractType,
);
// if the result is not a GraphQLObjectType we're fine
// If the result is not a GraphQLObjectType we're fine
if (!resultFromAutogenSchema || isString(resultFromAutogenSchema)) {
return resultFromAutogenSchema;
}
Expand All @@ -253,7 +248,6 @@ export class GraphQLFederationFactory {
// name of the type and hope apollo works it out
return resultFromAutogenSchema.name;
};

return unionInFederatedSchema;
return typeInFederatedSchema;
}
}

0 comments on commit af6edc0

Please sign in to comment.