-
Notifications
You must be signed in to change notification settings - Fork 2k
/
Copy pathexpressApollo.ts
67 lines (60 loc) · 1.7 KB
/
expressApollo.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import express from 'express';
import {
GraphQLOptions,
HttpQueryError,
runHttpQuery,
convertNodeHttpToRequest,
} from 'apollo-server-core';
import { ValueOrPromise } from 'apollo-server-env';
export interface ExpressGraphQLOptionsFunction {
(req?: express.Request, res?: express.Response): ValueOrPromise<
GraphQLOptions
>;
}
// Design principles:
// - there is just one way allowed: POST request with JSON body. Nothing else.
// - simple, fast and secure
//
export function graphqlExpress(
options: GraphQLOptions | ExpressGraphQLOptionsFunction,
): express.Handler {
if (!options) {
throw new Error('Apollo Server requires options.');
}
if (arguments.length > 1) {
throw new Error(
`Apollo Server expects exactly one argument, got ${arguments.length}`,
);
}
return (req, res, next): void => {
runHttpQuery([req, res], {
method: req.method,
options: options,
query: req.method === 'POST' ? req.body : req.query,
request: convertNodeHttpToRequest(req),
}).then(
({ graphqlResponse, responseInit }) => {
if (responseInit.headers) {
for (const [name, value] of Object.entries(responseInit.headers)) {
res.setHeader(name, value);
}
}
res.write(graphqlResponse);
res.end();
},
(error: HttpQueryError) => {
if ('HttpQueryError' !== error.name) {
return next(error);
}
if (error.headers) {
for (const [name, value] of Object.entries(error.headers)) {
res.setHeader(name, value);
}
}
res.statusCode = error.statusCode;
res.write(error.message);
res.end();
},
);
};
}