mirror of
https://github.com/vale981/apollo-server
synced 2025-03-16 15:56:41 -04:00

ApolloServer builds in graphql-playground rather than graphiql, so we no longer provide middleware for serving GraphiQL. If this turns out to be an unpopular choice, we can always add support for graphiql instead of graphql-playground back in later. We prefer graphql-playground because it allows you to enter HTTP request headers, view query history, and explicitly supports graphql@0.13.
77 lines
1.9 KiB
TypeScript
77 lines
1.9 KiB
TypeScript
import express from 'express';
|
|
import {
|
|
GraphQLOptions,
|
|
HttpQueryError,
|
|
runHttpQuery,
|
|
convertNodeHttpToRequest,
|
|
} from 'apollo-server-core';
|
|
|
|
export interface ExpressGraphQLOptionsFunction {
|
|
(req?: express.Request, res?: express.Response):
|
|
| GraphQLOptions
|
|
| Promise<GraphQLOptions>;
|
|
}
|
|
|
|
// Design principles:
|
|
// - there is just one way allowed: POST request with JSON body. Nothing else.
|
|
// - simple, fast and secure
|
|
//
|
|
|
|
export interface ExpressHandler {
|
|
(req: express.Request, res: express.Response, next): void;
|
|
}
|
|
|
|
export function graphqlExpress(
|
|
options: GraphQLOptions | ExpressGraphQLOptionsFunction,
|
|
): ExpressHandler {
|
|
if (!options) {
|
|
throw new Error('Apollo Server requires options.');
|
|
}
|
|
|
|
if (arguments.length > 1) {
|
|
// TODO: test this
|
|
throw new Error(
|
|
`Apollo Server expects exactly one argument, got ${arguments.length}`,
|
|
);
|
|
}
|
|
|
|
const graphqlHandler = (
|
|
req: express.Request,
|
|
res: express.Response,
|
|
next,
|
|
): void => {
|
|
runHttpQuery([req, res], {
|
|
method: req.method,
|
|
options: options,
|
|
query: req.method === 'POST' ? req.body : req.query,
|
|
request: convertNodeHttpToRequest(req),
|
|
}).then(
|
|
gqlResponse => {
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.setHeader(
|
|
'Content-Length',
|
|
Buffer.byteLength(gqlResponse, 'utf8').toString(),
|
|
);
|
|
res.write(gqlResponse);
|
|
res.end();
|
|
},
|
|
(error: HttpQueryError) => {
|
|
if ('HttpQueryError' !== error.name) {
|
|
return next(error);
|
|
}
|
|
|
|
if (error.headers) {
|
|
Object.keys(error.headers).forEach(header => {
|
|
res.setHeader(header, error.headers[header]);
|
|
});
|
|
}
|
|
|
|
res.statusCode = error.statusCode;
|
|
res.write(error.message);
|
|
res.end();
|
|
},
|
|
);
|
|
};
|
|
|
|
return graphqlHandler;
|
|
}
|