Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(createProxyingResolver): finish new functionality #1351

Merged
merged 1 commit into from Apr 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 5 additions & 10 deletions src/Interfaces.ts
Expand Up @@ -126,14 +126,12 @@ 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 +594,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