Skip to content

Commit

Permalink
refactor(createProxyingResolver): finish new functionality
Browse files Browse the repository at this point in the history
 = finishes work in #1349 for #1302
  =  streamlines the CreateProxyingResolverFn signature as no further arguments expected, pass along all info to users for possible customization
  =  adds fix for nested root query object to makeRemoteExecutableSchema
  = actually export defaultCreateProxyingResolver
  • Loading branch information
yaacovCR committed Apr 7, 2020
1 parent 511a81e commit 4c62a13
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 55 deletions.
18 changes: 5 additions & 13 deletions src/Interfaces.ts
Expand Up @@ -121,19 +121,14 @@ export interface IFetcherOperation {
context?: { [key: string]: any };
}

export type Dispatcher = (context: any) => ApolloLink | Fetcher;

export interface SubschemaConfig {
schema: GraphQLSchema;
rootValue?: Record<string, any>;
executor?: Delegator;
subscriber?: Delegator;
link?: ApolloLink;
fetcher?: Fetcher;
dispatcher?: Dispatcher;
createProxyingResolver?: CreateProxyingResolverFn;
transforms?: Array<Transform>;
merge?: Record<string, MergedTypeConfig>;
createProxyingResolver?: CreateProxyingResolverFn;
}

export interface MergedTypeConfig {
Expand Down Expand Up @@ -596,12 +591,9 @@ export type DirectiveMapper = (
schema: GraphQLSchema,
) => GraphQLDirective | null | undefined;

export interface ICreateProxyingResolverOptions {
schema?: GraphQLSchema | SubschemaConfig;
transforms?: Array<Transform>;
operation?: Operation;
}

export type CreateProxyingResolverFn = (
options: ICreateProxyingResolverOptions,
schema: GraphQLSchema | SubschemaConfig,
transforms: Array<Transform>,
operation: Operation,
fieldName: string,
) => GraphQLFieldResolver<any, any>;
2 changes: 2 additions & 0 deletions src/wrap/index.ts
@@ -1,6 +1,8 @@
export { wrapSchema } from './wrapSchema';
export { transformSchema } from './transformSchema';

export { defaultCreateProxyingResolver } from './resolvers';

export * from './transforms/index';

export {
Expand Down
34 changes: 10 additions & 24 deletions src/wrap/makeRemoteExecutableSchema.ts
Expand Up @@ -8,9 +8,7 @@ import {
DocumentNode,
} from 'graphql';

import { addResolversToSchema } from '../generate/index';
import { Fetcher, Operation } from '../Interfaces';
import { cloneSchema } from '../utils/index';
import { Fetcher } from '../Interfaces';
import { buildSchema } from '../polyfills/index';
import { addTypenameToAbstract } from '../delegate/addTypenameToAbstract';
import { checkResultAndHandleErrors } from '../delegate/checkResultAndHandleErrors';
Expand All @@ -19,7 +17,7 @@ import linkToFetcher, { execute } from '../stitch/linkToFetcher';
import { observableToAsyncIterable } from '../stitch/observableToAsyncIterable';
import mapAsyncIterator from '../stitch/mapAsyncIterator';

import { stripResolvers, generateProxyingResolvers } from './resolvers';
import { wrapSchema } from './wrapSchema';

export type ResolverFn = (
rootValue?: any,
Expand Down Expand Up @@ -56,27 +54,15 @@ export default function makeRemoteExecutableSchema({
? buildSchema(schemaOrTypeDefs, buildSchemaOptions)
: schemaOrTypeDefs;

const createProxyingResolver = ({
operation,
}: {
operation: Operation;
}): GraphQLFieldResolver<any, any> => {
if (operation === 'query' || operation === 'mutation') {
return createResolver(finalFetcher);
}
return createSubscriptionResolver(link);
};

const resolvers = generateProxyingResolvers({
subschemaConfig: { schema: targetSchema, createProxyingResolver },
return wrapSchema({
schema: targetSchema,
createProxyingResolver: (_schema, _transforms, operation) => {
if (operation === 'query' || operation === 'mutation') {
return createResolver(finalFetcher);
}
return createSubscriptionResolver(link);
},
});

const remoteSchema = cloneSchema(targetSchema);

stripResolvers(remoteSchema);
addResolversToSchema({ schema: remoteSchema, resolvers });

return remoteSchema;
}

export function defaultCreateRemoteResolver(
Expand Down
50 changes: 32 additions & 18 deletions src/wrap/resolvers.ts
Expand Up @@ -40,20 +40,29 @@ export function generateProxyingResolvers({

const resolvers = {};
Object.keys(operationTypes).forEach((operation: Operation) => {
const resolveField = operation === 'subscription' ? 'subscribe' : 'resolve';

const rootType = operationTypes[operation];
if (rootType != null) {
const typeName = rootType.name;
const fields = rootType.getFields();

resolvers[typeName] = {};
Object.keys(fields).forEach((fieldName) => {
const resolveField =
operation === 'subscription' ? 'subscribe' : 'resolve';
const proxyingResolver = createProxyingResolver(
subschemaConfig,
transforms,
operation,
fieldName,
);

const finalResolver = createPossiblyNestedProxyingResolver(
subschemaConfig,
proxyingResolver,
);

resolvers[typeName][fieldName] = {
[resolveField]: createProxyingResolver({
schema: subschemaConfig,
transforms,
operation,
}),
[resolveField]: finalResolver,
};
});
}
Expand All @@ -62,14 +71,11 @@ export function generateProxyingResolvers({
return resolvers;
}

function defaultCreateProxyingResolver({
schema,
transforms,
}: {
schema: SubschemaConfig;
transforms: Array<Transform>;
}): GraphQLFieldResolver<any, any> {
return (parent, _args, context, info) => {
function createPossiblyNestedProxyingResolver(
subschemaConfig: SubschemaConfig,
proxyingResolver: GraphQLFieldResolver<any, any>,
): GraphQLFieldResolver<any, any> {
return (parent, args, context, info) => {
if (parent != null) {
const responseKey = getResponseKeyFromInfo(info);
const errors = getErrors(parent, responseKey);
Expand All @@ -81,7 +87,7 @@ function defaultCreateProxyingResolver({
// If there is a proxied result from this subschema, return it
// This can happen even for a root field when the root type ia
// also nested as a field within a different type.
if (schema === subschema) {
if (subschemaConfig === subschema) {
return handleResult(
parent[responseKey],
errors,
Expand All @@ -93,13 +99,21 @@ function defaultCreateProxyingResolver({
}
}

return delegateToSchema({
return proxyingResolver(parent, args, context, info);
};
}

export function defaultCreateProxyingResolver(
schema: GraphQLSchema | SubschemaConfig,
transforms: Array<Transform>,
): GraphQLFieldResolver<any, any> {
return (_parent, _args, context, info) =>
delegateToSchema({
schema,
context,
info,
transforms,
});
};
}

export function stripResolvers(schema: GraphQLSchema): void {
Expand Down

0 comments on commit 4c62a13

Please sign in to comment.