move formatError and formatResponse into runQuery

This commit is contained in:
Jonas Helfer 2016-06-27 21:58:22 -04:00
parent 09ac4c09d7
commit 058f9a7862
2 changed files with 32 additions and 17 deletions

View file

@ -5,6 +5,8 @@ import {
parse,
validate,
execute,
formatError,
// specifiedRules, // TODO: this isn't in the type definitions yet, so we can't import it.
} from 'graphql';
export interface GqlResponse {
@ -20,6 +22,9 @@ export interface QueryOptions {
variables?: { [key: string]: any };
operationName?: string;
logFunction?: Function;
validationRules?: Array<Function>;
formatError?: Function;
formatResponse?: Function;
}
function runQuery(options: QueryOptions): Promise<GraphQLResult> {
@ -36,6 +41,13 @@ function runQuery(options: QueryOptions): Promise<GraphQLResult> {
}
// TODO: time this with log function
// TODO: allow extra validationRules
// let rules = specifiedRules;
// if (options.validationRules) {
// rules = rules.concat(options.validationRules);
// }
// const validationErrors = validate(options.schema, documentAST, rules);
const validationErrors = validate(options.schema, documentAST);
if (validationErrors.length) {
return Promise.resolve({ errors: validationErrors });
@ -52,7 +64,19 @@ function runQuery(options: QueryOptions): Promise<GraphQLResult> {
options.context,
options.variables,
options.operationName
);
).then(gqlResponse => {
let response = {
data: gqlResponse.data,
};
if (gqlResponse.errors) {
response['errors'] = gqlResponse.errors.map(options.formatError || formatError as any);
// TODO: stop any creep. Fix the issue here.
}
if (options.formatResponse) {
response = options.formatResponse(response);
}
return response;
});
} catch (executionError) {
return Promise.resolve({ errors: [ executionError ] });
}

View file

@ -13,6 +13,7 @@ export interface ExpressApolloOptions {
rootValue?: any;
context?: any;
logFunction?: Function;
validationRules?: Array<Function>; // validation rules are functions
formatResponse?: Function;
}
@ -57,6 +58,8 @@ export function graphqlHTTP(options: ExpressApolloOptions | ExpressApolloOptions
}
const b = req.body;
// TODO: do something different here if the body is an array.
// Throw an error if body isn't either array or object.
const query = b.query;
const operationName = b.operationName;
let variables = b.variables;
@ -66,11 +69,6 @@ export function graphqlHTTP(options: ExpressApolloOptions | ExpressApolloOptions
variables = JSON.parse(variables);
}
// either query or operationName must be present. Return 400 otherwise
// if only operationName is present, check if it's in store. Return 400 otherwise
// TODO: in store, fragments should only have to be written once, then used across queries.
if (!query) {
throw httpError(400, 'Must provide query string.');
}
@ -82,22 +80,15 @@ export function graphqlHTTP(options: ExpressApolloOptions | ExpressApolloOptions
rootValue: optionsObject.rootValue,
operationName: operationName,
logFunction: optionsObject.logFunction,
validationRules: optionsObject.validationRules,
formatError: optionsObject.formatError,
formatResponse: optionsObject.formatResponse,
}).then(gqlResponse => {
res.set('Content-Type', 'application/json');
if (gqlResponse.errors && typeof gqlResponse.data === 'undefined') {
res.status(400);
}
let response = {
data: gqlResponse.data,
};
if (gqlResponse.errors) {
response['errors'] = gqlResponse.errors.map(optionsObject.formatError || graphql.formatError as any);
// TODO: stop any creep. Fix the issue here.
}
if (optionsObject.formatResponse) {
response = optionsObject.formatResponse(response);
}
res.send(JSON.stringify(response));
res.send(JSON.stringify(gqlResponse));
});
};
}