@graphql-tools/stitch
Version:
A set of utils for faster development of GraphQL tools
54 lines (53 loc) • 2.4 kB
JavaScript
import { delegateToSchema, isSubschemaConfig } from '@graphql-tools/delegate';
import { getFragmentsFromDocument } from '@graphql-tools/executor';
import { collectFields, getDefinedRootType, getOperationASTFromRequest, } from '@graphql-tools/utils';
/**
* Creates an executor that uses the schema created by stitching together multiple subschemas.
* Not ready for production
* Breaking changes can be introduced in the meanwhile
*
* @experimental
*
*/
export function createStitchingExecutor(stitchedSchema) {
const subschemas = [
...(stitchedSchema.extensions?.['stitchingInfo']).subschemaMap.values(),
];
return async function stitchingExecutor(executorRequest) {
const fragments = getFragmentsFromDocument(executorRequest.document);
const operation = getOperationASTFromRequest(executorRequest);
const rootType = getDefinedRootType(stitchedSchema, operation.operation);
const { fields } = collectFields(stitchedSchema, fragments, executorRequest.variables, rootType, operation.selectionSet);
const data = {};
for (const [fieldName, fieldNodes] of fields) {
const responseKey = fieldNodes[0].alias?.value ?? fieldName;
const subschemaForField = subschemas.find(subschema => {
const subschemaSchema = isSubschemaConfig(subschema)
? subschema.schema
: subschema;
const rootType = getDefinedRootType(subschemaSchema, operation.operation);
return rootType.getFields()[fieldName] != null;
});
let result = await delegateToSchema({
schema: subschemaForField || stitchedSchema,
rootValue: executorRequest.rootValue,
context: executorRequest.context,
info: {
schema: stitchedSchema,
fieldName,
fieldNodes,
operation,
fragments,
parentType: rootType,
returnType: rootType.getFields()[fieldName].type,
variableValues: executorRequest.variables,
},
});
if (Array.isArray(result)) {
result = await Promise.all(result);
}
data[responseKey] = result;
}
return { data };
};
}