Skip to content
This repository has been archived by the owner on Apr 15, 2020. It is now read-only.

Commit

Permalink
refactor(stitching)
Browse files Browse the repository at this point in the history
- Default delegateToSchema operation to the original operation for root fields and query otherwise.
- Change mergeTypes option to skipTypeMerging to reverse default so that skipTypeMerging should be specified for mergeTypeResolvers but can be omitted for stitching on gateway
- serialize original variable values so that they can be ommited by default
  • Loading branch information
yaacovCR committed Mar 26, 2020
1 parent d83ae2c commit f2330a6
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 41 deletions.
6 changes: 3 additions & 3 deletions src/Interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export function isSubschemaConfig(value: SchemaLikeObject): value is SubschemaCo

export interface IDelegateToSchemaOptions<TContext = { [key: string]: any }> {
schema: GraphQLSchema | SubschemaConfig;
operation: Operation;
operation?: Operation;
fieldName: string;
returnType?: GraphQLOutputType;
args?: { [key: string]: any };
Expand All @@ -133,7 +133,7 @@ export interface IDelegateToSchemaOptions<TContext = { [key: string]: any }> {
rootValue?: Record<string, any>;
transforms?: Array<Transform>;
skipValidation?: boolean;
mergeTypes?: boolean;
skipTypeMerging?: boolean;
}

export interface ICreateDelegatingRequestOptions {
Expand All @@ -156,7 +156,7 @@ export interface IDelegateRequestOptions<TContext = { [key: string]: any }> {
returnType?: GraphQLOutputType;
context?: TContext;
transforms?: Array<Transform>;
mergeTypes?: boolean;
skipTypeMerging?: boolean;
}

export type Delegator = ({ document, context, variables }: {
Expand Down
30 changes: 14 additions & 16 deletions src/stitching/checkResultAndHandleErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function checkResultAndHandleErrors(
responseKey?: string,
subschema?: GraphQLSchema | SubschemaConfig,
returnType: GraphQLOutputType = info.returnType,
mergeTypes?: boolean,
skipTypeMerging?: boolean,
): any {
if (!responseKey) {
responseKey = getResponseKeyFromInfo(info);
Expand All @@ -46,7 +46,7 @@ export function checkResultAndHandleErrors(
const data = result.data && result.data[responseKey];
const subschemas = [subschema];

return handleResult(data, errors, subschemas, context, info, returnType, mergeTypes);
return handleResult(data, errors, subschemas, context, info, returnType, skipTypeMerging);
}

export function handleResult(
Expand All @@ -56,7 +56,7 @@ export function handleResult(
context: Record<string, any>,
info: IGraphQLToolsResolveInfo,
returnType = info.returnType,
mergeTypes?: boolean,
skipTypeMerging?: boolean,
): any {
const type = getNullableType(returnType);

Expand All @@ -67,9 +67,9 @@ export function handleResult(
if (isLeafType(type)) {
return type.parseValue(result);
} else if (isCompositeType(type)) {
return handleObject(type, result, errors, subschemas, context, info, mergeTypes);
return handleObject(type, result, errors, subschemas, context, info, skipTypeMerging);
} else if (isListType(type)) {
return handleList(type, result, errors, subschemas, context, info, mergeTypes);
return handleList(type, result, errors, subschemas, context, info, skipTypeMerging);
}
}

Expand All @@ -95,20 +95,19 @@ export function handleObject(
subschemas: Array<GraphQLSchema | SubschemaConfig>,
context: Record<string, any>,
info: IGraphQLToolsResolveInfo,
mergeTypes?: boolean,
skipTypeMerging?: boolean,
) {
makeObjectProxiedResult(object, errors, subschemas);

if (mergeTypes && info.mergeInfo) {
if (skipTypeMerging || !info.mergeInfo) {
return object;
} else {
return mergeFields(
type,
object,
subschemas,
context,
info,
);
} else {
return object;
}
}

Expand All @@ -119,9 +118,8 @@ function handleList(
subschemas: Array<GraphQLSchema | SubschemaConfig>,
context: Record<string, any>,
info: IGraphQLToolsResolveInfo,
mergeTypes?: boolean,
skipTypeMerging?: boolean,
) {

const childErrors = getErrorsByPathSegment(errors);

list = list.map((listMember, index) => handleListMember(
Expand All @@ -132,7 +130,7 @@ function handleList(
subschemas,
context,
info,
mergeTypes,
skipTypeMerging,
));

return list;
Expand All @@ -146,7 +144,7 @@ function handleListMember(
subschemas: Array<GraphQLSchema | SubschemaConfig>,
context: Record<string, any>,
info: IGraphQLToolsResolveInfo,
mergeTypes?: boolean,
skipTypeMerging?: boolean,
): any {
if (listMember == null) {
return handleNull(info.fieldNodes, [...responsePathAsArray(info.path), index], errors);
Expand All @@ -155,9 +153,9 @@ function handleListMember(
if (isLeafType(type)) {
return type.parseValue(listMember);
} else if (isCompositeType(type)) {
return handleObject(type, listMember, errors, subschemas, context, info, mergeTypes);
return handleObject(type, listMember, errors, subschemas, context, info, skipTypeMerging);
} else if (isListType(type)) {
return handleList(type, listMember, errors, subschemas, context, info, mergeTypes);
return handleList(type, listMember, errors, subschemas, context, info, skipTypeMerging);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/stitching/defaultMergedResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ export default function defaultMergedResolver(
const result = parent[responseKey];
const subschemas = getSubschemas(parent);

return handleResult(result, errors, subschemas, context, info, undefined, true);
return handleResult(result, errors, subschemas, context, info);
}
51 changes: 37 additions & 14 deletions src/stitching/delegateToSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import {
validate,
GraphQLSchema,
ExecutionResult,
GraphQLObjectType,
OperationTypeNode,
typeFromAST,
NamedTypeNode,
GraphQLInputType,
} from 'graphql';

import {
Expand Down Expand Up @@ -45,6 +50,20 @@ import { observableToAsyncIterable } from './observableToAsyncIterable';
import { AddMergedTypeFragments } from '../transforms';

import { isAsyncIterable } from 'iterall';
import { serializeInputValue } from '../utils';

function getDelegatingOperation(
parentType: GraphQLObjectType,
schema: GraphQLSchema
): OperationTypeNode {
if (parentType === schema.getMutationType()) {
return 'mutation';
} else if (parentType === schema.getSubscriptionType()) {
return 'subscription';
} else {
return 'query';
}
}

export default function delegateToSchema(
options: IDelegateToSchemaOptions | GraphQLSchema,
Expand All @@ -60,14 +79,14 @@ export default function delegateToSchema(
schema: subschema,
rootValue,
info,
operation = info.operation.operation,
operation = getDelegatingOperation(info.parentType, info.schema),
fieldName,
returnType = info.returnType,
args,
context,
transforms = [],
skipValidation,
mergeTypes,
skipTypeMerging,
} = options;

const request = createDelegatingRequest({
Expand All @@ -90,14 +109,14 @@ export default function delegateToSchema(
returnType,
context,
transforms,
mergeTypes,
skipTypeMerging,
});
}

export function createDelegatingRequest({
schema: subschema,
info,
operation = info.operation.operation,
operation = getDelegatingOperation(info.parentType, info.schema),
fieldName,
args,
transforms = [],
Expand Down Expand Up @@ -132,10 +151,6 @@ export function createDelegatingRequest({
transforms.push(
new AddArgumentsAsVariables(targetSchema, args, info.schema)
);
} else {
console.warn(
'"args" undefined. "args" argument may be required in a future version. Custom scalars or enums may not be properly serialized prior to delegation.'
);
}

transforms.push(
Expand All @@ -160,12 +175,12 @@ export function delegateRequest({
schema: subschema,
rootValue,
info,
operation = info.operation.operation,
operation,
fieldName,
returnType = info.returnType,
context,
transforms = [],
mergeTypes,
skipTypeMerging,
}: IDelegateRequestOptions): any {
let targetSchema: GraphQLSchema;
let subschemaConfig: SubschemaConfig;
Expand All @@ -181,7 +196,7 @@ export function delegateRequest({
}

transforms = [
new CheckResultAndHandleErrors(info, fieldName, subschema, context, returnType, mergeTypes),
new CheckResultAndHandleErrors(info, fieldName, subschema, context, returnType, skipTypeMerging),
...transforms,
];

Expand Down Expand Up @@ -261,7 +276,7 @@ function createInitialRequest(
selectionSet,
name: {
kind: Kind.NAME,
value: targetField,
value: targetField || info.fieldNodes[0].name.value,
},
};

Expand All @@ -272,7 +287,7 @@ function createInitialRequest(

const operationDefinition: OperationDefinitionNode = {
kind: Kind.OPERATION_DEFINITION,
operation: targetOperation,
operation: targetOperation || getDelegatingOperation(info.parentType, info.schema),
variableDefinitions: info.operation.variableDefinitions,
selectionSet: rootSelectionSet,
name: info.operation.name,
Expand All @@ -287,9 +302,17 @@ function createInitialRequest(
definitions: [operationDefinition, ...fragments],
};

const variableValues = info.variableValues;
const variables = {};
for (const variableDefinition of info.operation.variableDefinitions) {
const varName = variableDefinition.variable.name.value;
const varType = typeFromAST(info.schema, (variableDefinition.type as NamedTypeNode)) as GraphQLInputType;
variables[varName] = serializeInputValue(varType, variableValues[varName]);
}

return {
document,
variables: info.variableValues,
variables,
};
}

Expand Down
3 changes: 0 additions & 3 deletions src/stitching/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,9 @@ function defaultCreateProxyingResolver(
): GraphQLFieldResolver<any, any> {
return (parent, args, context, info) => delegateToSchema({
schema: subschemaConfig,
operation,
fieldName,
args,
context,
info,
mergeTypes: true,
});
}

Expand Down
2 changes: 2 additions & 0 deletions src/test/testAlternateMergeSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1760,6 +1760,7 @@ describe('mergeTypes', () => {
args: { id: originalResult.id },
context,
info,
skipTypeMerging: true,
})
}
},
Expand All @@ -1777,6 +1778,7 @@ describe('mergeTypes', () => {
args: { id: originalResult.id },
context,
info,
skipTypeMerging: true,
})
}
},
Expand Down
8 changes: 4 additions & 4 deletions src/transforms/CheckResultAndHandleErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ export default class CheckResultAndHandleErrors implements Transform {
private fieldName?: string;
private subschema?: GraphQLSchema | SubschemaConfig;
private returnType?: GraphQLOutputType;
private mergeTypes?: boolean;
private typeMerge?: boolean;

constructor(
info: IGraphQLToolsResolveInfo,
fieldName?: string,
subschema?: GraphQLSchema | SubschemaConfig,
context?: Record<string, any>,
returnType: GraphQLOutputType = info.returnType,
mergeTypes?: boolean,
typeMerge?: boolean,
) {
this.context = context;
this.info = info;
this.fieldName = fieldName;
this.subschema = subschema;
this.returnType = returnType;
this.mergeTypes = mergeTypes;
this.typeMerge = typeMerge;
}

public transformResult(result: any): any {
Expand All @@ -35,7 +35,7 @@ export default class CheckResultAndHandleErrors implements Transform {
this.fieldName,
this.subschema,
this.returnType,
this.mergeTypes,
this.typeMerge,
);
}
}

0 comments on commit f2330a6

Please sign in to comment.