apollo-server/src/integrations/expressApollo.ts

61 lines
1.9 KiB
TypeScript
Raw Normal View History

2016-06-12 22:41:46 -07:00
import * as express from 'express';
import * as graphql from 'graphql';
import { runQuery } from '../core/runQuery';
2016-06-12 22:41:46 -07:00
2016-06-15 20:35:48 -07:00
import { renderGraphiQL, GraphiQLData } from '../modules/renderGraphiQL';
// TODO: will these be the same or different for other integrations?
export interface ExpressApolloOptions {
2016-06-12 22:41:46 -07:00
schema: graphql.GraphQLSchema;
2016-06-15 20:35:48 -07:00
formatError?: Function;
rootValue?: any;
context?: any;
logFunction?: Function;
// TODO: does this need to be able to take a promise as well, like express-graphql does?
// answer: yes, it does. Func(req) => options
2016-06-12 22:41:46 -07:00
}
2016-06-15 20:35:48 -07:00
export function graphqlHTTP(options: ExpressApolloOptions) {
2016-06-12 22:41:46 -07:00
if (!options) {
2016-06-15 20:35:48 -07:00
throw new Error('Apollo graphqlHTTP middleware requires options.');
2016-06-12 22:41:46 -07:00
}
2016-06-12 22:41:46 -07:00
if (arguments.length > 1) {
throw new Error(`apolloServer expects exactly one argument, got ${arguments.length + 1}`);
}
2016-06-12 22:41:46 -07:00
return (req: express.Request, res: express.Response, next) => {
return runQuery({
schema: options.schema,
query: getQueryString(req),
}).then(gqlResponse => {
res.set('Content-Type', 'application/json');
2016-06-15 20:35:48 -07:00
res.send({ data: gqlResponse.data, errors: gqlResponse.errors });
});
};
}
function getQueryString(req: express.Request): string {
if (req.method === 'POST') {
return req.body;
} else if (req.method === 'GET') {
return req.query['query'];
}
throw new Error(`HTTP method ${req.method} not supported`);
}
2016-06-15 20:35:48 -07:00
// this returns the html for the GraphiQL interactive query UI
// TODO: it's still missing a way to tell it where the GraphQL endpoint is.
export function renderGraphiQL(options: GraphiQLData) {
return (req: express.Request, res: express.Response, next) => {
const graphiQLString = renderGraphiQL({
query: options.query,
variables: options.variables,
operationName: options.operationName,
result: options.result,
});
2016-06-15 20:35:48 -07:00
res.set('Content-Type', 'text/html');
res.send(graphiQLString);
};
2016-06-12 22:41:46 -07:00
}