diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 1ffe9fa815c..b3bab8f5694 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -133,6 +133,7 @@ export interface SubschemaConfig { dispatcher?: Dispatcher; transforms?: Array; merge?: Record; + createProxyingResolver?: CreateProxyingResolverFn; } export interface MergedTypeConfig { @@ -594,3 +595,13 @@ export type DirectiveMapper = ( directive: GraphQLDirective, schema: GraphQLSchema, ) => GraphQLDirective | null | undefined; + +export interface ICreateProxyingResolverOptions { + schema?: GraphQLSchema | SubschemaConfig; + transforms?: Array; + operation?: Operation; +} + +export type CreateProxyingResolverFn = ( + options: ICreateProxyingResolverOptions, +) => GraphQLFieldResolver; diff --git a/src/wrap/index.ts b/src/wrap/index.ts index 6ae24b4e457..5f1ca3dbed1 100644 --- a/src/wrap/index.ts +++ b/src/wrap/index.ts @@ -6,4 +6,5 @@ export * from './transforms/index'; export { default as makeRemoteExecutableSchema, defaultCreateRemoteResolver, + defaultCreateRemoteSubscriptionResolver, } from './makeRemoteExecutableSchema'; diff --git a/src/wrap/makeRemoteExecutableSchema.ts b/src/wrap/makeRemoteExecutableSchema.ts index 68e173acb7f..0f129f4de39 100644 --- a/src/wrap/makeRemoteExecutableSchema.ts +++ b/src/wrap/makeRemoteExecutableSchema.ts @@ -33,12 +33,16 @@ export default function makeRemoteExecutableSchema({ link, fetcher, createResolver = defaultCreateRemoteResolver, + createSubscriptionResolver = defaultCreateRemoteSubscriptionResolver, buildSchemaOptions, }: { schema: GraphQLSchema | string; link?: ApolloLink; fetcher?: Fetcher; createResolver?: (fetcher: Fetcher) => GraphQLFieldResolver; + createSubscriptionResolver?: ( + link: ApolloLink, + ) => GraphQLFieldResolver; buildSchemaOptions?: BuildSchemaOptions; }): GraphQLSchema { let finalFetcher: Fetcher = fetcher; @@ -52,31 +56,26 @@ export default function makeRemoteExecutableSchema({ ? buildSchema(schemaOrTypeDefs, buildSchemaOptions) : schemaOrTypeDefs; - const remoteSchema = cloneSchema(targetSchema); - stripResolvers(remoteSchema); - - function createProxyingResolver({ + const createProxyingResolver = ({ operation, }: { operation: Operation; - }): GraphQLFieldResolver { + }): GraphQLFieldResolver => { if (operation === 'query' || operation === 'mutation') { return createResolver(finalFetcher); } return createSubscriptionResolver(link); - } + }; - addResolversToSchema({ - schema: remoteSchema, - resolvers: generateProxyingResolvers({ - subschemaConfig: { schema: remoteSchema }, - createProxyingResolver, - }), - resolverValidationOptions: { - allowResolversNotInSchema: true, - }, + const resolvers = generateProxyingResolvers({ + subschemaConfig: { schema: targetSchema, createProxyingResolver }, }); + const remoteSchema = cloneSchema(targetSchema); + + stripResolvers(remoteSchema); + addResolversToSchema({ schema: remoteSchema, resolvers }); + return remoteSchema; } @@ -103,7 +102,9 @@ export function defaultCreateRemoteResolver( }; } -function createSubscriptionResolver(link: ApolloLink): ResolverFn { +export function defaultCreateRemoteSubscriptionResolver( + link: ApolloLink, +): GraphQLFieldResolver { return (_root, _args, context, info) => { const fragments = Object.keys(info.fragments).map( (fragment) => info.fragments[fragment], diff --git a/src/wrap/resolvers.ts b/src/wrap/resolvers.ts index ba03a34e6b2..894e20c79c9 100644 --- a/src/wrap/resolvers.ts +++ b/src/wrap/resolvers.ts @@ -21,21 +21,9 @@ import { getErrors } from '../stitch/errors'; export function generateProxyingResolvers({ subschemaConfig, transforms, - createProxyingResolver = defaultCreateProxyingResolver, }: { subschemaConfig: SubschemaConfig; transforms?: Array; - createProxyingResolver?: ({ - schema, - transforms, - operation, - fieldName, - }: { - schema?: GraphQLSchema | SubschemaConfig; - transforms?: Array; - operation?: Operation; - fieldName?: string; - }) => GraphQLFieldResolver; }): IResolvers { const targetSchema = subschemaConfig.schema; @@ -45,6 +33,11 @@ export function generateProxyingResolvers({ subscription: targetSchema.getSubscriptionType(), }; + const createProxyingResolver = + subschemaConfig.createProxyingResolver != null + ? subschemaConfig.createProxyingResolver + : defaultCreateProxyingResolver; + const resolvers = {}; Object.keys(operationTypes).forEach((operation: Operation) => { const rootType = operationTypes[operation]; @@ -58,9 +51,8 @@ export function generateProxyingResolvers({ resolvers[typeName][fieldName] = { [resolveField]: createProxyingResolver({ schema: subschemaConfig, - operation, - fieldName, transforms, + operation, }), }; }); diff --git a/src/wrap/wrapSchema.ts b/src/wrap/wrapSchema.ts index b9904838dff..312a5ca66e7 100644 --- a/src/wrap/wrapSchema.ts +++ b/src/wrap/wrapSchema.ts @@ -18,13 +18,16 @@ export function wrapSchema( : { schema: subschemaOrSubschemaConfig }; const schema = cloneSchema(subschemaConfig.schema); + stripResolvers(schema); - addResolversToSchema({ - schema, - resolvers: generateProxyingResolvers({ subschemaConfig, transforms }), + const resolvers = generateProxyingResolvers({ + subschemaConfig, + transforms, }); + addResolversToSchema({ schema, resolvers }); + let schemaTransforms: Array = []; if (subschemaConfig.transforms != null) { schemaTransforms = schemaTransforms.concat(subschemaConfig.transforms);