Skip to content

Commit

Permalink
Add pluggable executor to request pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
martijnwalraven committed Mar 7, 2019
1 parent 3a3c67d commit 185dd45
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 14 deletions.
2 changes: 2 additions & 0 deletions packages/apollo-server-core/src/graphqlOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { KeyValueCache, InMemoryLRUCache } from 'apollo-server-caching';
import { DataSource } from 'apollo-datasource';
import { ApolloServerPlugin } from 'apollo-server-plugin-base';
import { GraphQLParseOptions } from 'graphql-tools';
import { GraphQLExecutor } from '../dist/requestPipelineAPI';

/*
* GraphQLServerOptions
Expand All @@ -37,6 +38,7 @@ export interface GraphQLServerOptions<
rootValue?: ((parsedQuery: DocumentNode) => TRootValue) | TRootValue;
context?: TContext | (() => never);
validationRules?: Array<(context: ValidationContext) => any>;
executor?: GraphQLExecutor;
formatResponse?: Function;
fieldResolver?: GraphQLFieldResolver<any, TContext>;
debug?: boolean;
Expand Down
33 changes: 20 additions & 13 deletions packages/apollo-server-core/src/requestPipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
DocumentNode,
getOperationAST,
ExecutionArgs,
ExecutionResult,
GraphQLError,
GraphQLFormattedError,
} from 'graphql';
Expand Down Expand Up @@ -36,6 +35,7 @@ import {
GraphQLRequestContext,
InvalidGraphQLRequestError,
ValidationRule,
GraphQLExecutor,
} from '../dist/requestPipelineAPI';
import {
ApolloServerPlugin,
Expand Down Expand Up @@ -67,6 +67,7 @@ export interface GraphQLRequestPipelineConfig<TContext> {

rootValue?: ((document: DocumentNode) => any) | any;
validationRules?: ValidationRule[];
executor?: GraphQLExecutor;
fieldResolver?: GraphQLFieldResolver<any, TContext>;

dataSources?: () => DataSources<TContext>;
Expand Down Expand Up @@ -284,11 +285,10 @@ export async function processGraphQLRequest<TContext>(
let response: GraphQLResponse;

try {
response = (await execute(
requestContext.document,
request.operationName,
request.variables,
)) as GraphQLResponse;
response = await execute(requestContext as WithRequired<
typeof requestContext,
'document' | 'operation' | 'operationName'
>);
executionDidEnd();
} catch (executionError) {
executionDidEnd(executionError);
Expand Down Expand Up @@ -342,10 +342,13 @@ export async function processGraphQLRequest<TContext>(
}

async function execute(
document: DocumentNode,
operationName: GraphQLRequest['operationName'],
variables: GraphQLRequest['variables'],
): Promise<ExecutionResult> {
requestContext: WithRequired<
GraphQLRequestContext<TContext>,
'document' | 'operationName' | 'operation'
>,
): Promise<GraphQLResponse> {
const { request, document } = requestContext;

const executionArgs: ExecutionArgs = {
schema: config.schema,
document,
Expand All @@ -354,8 +357,8 @@ export async function processGraphQLRequest<TContext>(
? config.rootValue(document)
: config.rootValue,
contextValue: requestContext.context,
variableValues: variables,
operationName,
variableValues: request.variables,
operationName: request.operationName,
fieldResolver: config.fieldResolver,
};

Expand All @@ -364,7 +367,11 @@ export async function processGraphQLRequest<TContext>(
});

try {
return await graphql.execute(executionArgs);
if (config.executor) {
return await config.executor(requestContext);
} else {
return (await graphql.execute(executionArgs)) as GraphQLResponse;
}
} finally {
executionDidEnd();
}
Expand Down
14 changes: 13 additions & 1 deletion packages/apollo-server-core/src/requestPipelineAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
// circular dependency issues from the `apollo-server-plugin-base` package
// depending on the types in it.

import { Request, Response } from 'apollo-server-env';
import {
Request,
Response,
ValueOrPromise,
WithRequired,
} from 'apollo-server-env';
import {
GraphQLSchema,
ValidationContext,
Expand Down Expand Up @@ -63,3 +68,10 @@ export interface GraphQLRequestContext<TContext = Record<string, any>> {
export type ValidationRule = (context: ValidationContext) => ASTVisitor;

export class InvalidGraphQLRequestError extends Error {}

export type GraphQLExecutor<TContext = Record<string, any>> = (
requestContext: WithRequired<
GraphQLRequestContext<TContext>,
'document' | 'operationName' | 'operation'
>,
) => ValueOrPromise<GraphQLResponse>;
1 change: 1 addition & 0 deletions packages/apollo-server-core/src/runHttpQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export async function runHttpQuery(
rootValue: options.rootValue,
context: options.context || {},
validationRules: options.validationRules,
executor: options.executor,
fieldResolver: options.fieldResolver,

// FIXME: Use proper option types to ensure this
Expand Down
1 change: 1 addition & 0 deletions packages/apollo-server-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type BaseConfig = Pick<
| 'debug'
| 'rootValue'
| 'validationRules'
| 'executor'
| 'formatResponse'
| 'fieldResolver'
| 'tracing'
Expand Down

0 comments on commit 185dd45

Please sign in to comment.