Skip to content

Commit 5578496

Browse files
committed
Make the middleware async, as supported by Express v5
1 parent 0446a10 commit 5578496

2 files changed

Lines changed: 30 additions & 31 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ Based on `@apollo/server/express4`, updated for Express v5.
99
The check to see if you forgot to install the JSON body parser now works with
1010
`body-parser` v2 (and thus `express.json()` in Express v5) as well as with the
1111
older version.
12+
13+
The middleware is now written as an async function, as supported in Express v5.

src/index.ts

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export function expressMiddleware<TContext extends BaseContext>(
4545
const context: ContextFunction<[ExpressContextFunctionArgument], TContext> =
4646
options?.context ?? defaultContext;
4747

48-
return (req, res, next) => {
48+
return async (req, res) => {
4949
if (!('body' in req)) {
5050
// The json body-parser *always* initializes the `body` field on requests
5151
// when it runs. (body-parser@1 (included in Express v4 as
@@ -84,37 +84,34 @@ export function expressMiddleware<TContext extends BaseContext>(
8484
body: req.body,
8585
};
8686

87-
server
88-
.executeHTTPGraphQLRequest({
89-
httpGraphQLRequest,
90-
context: () => context({ req, res }),
91-
})
92-
.then(async (httpGraphQLResponse) => {
93-
for (const [key, value] of httpGraphQLResponse.headers) {
94-
res.setHeader(key, value);
95-
}
96-
res.statusCode = httpGraphQLResponse.status || 200;
87+
const httpGraphQLResponse = await server.executeHTTPGraphQLRequest({
88+
httpGraphQLRequest,
89+
context: () => context({ req, res }),
90+
});
9791

98-
if (httpGraphQLResponse.body.kind === 'complete') {
99-
res.send(httpGraphQLResponse.body.string);
100-
return;
101-
}
92+
for (const [key, value] of httpGraphQLResponse.headers) {
93+
res.setHeader(key, value);
94+
}
95+
res.statusCode = httpGraphQLResponse.status || 200;
96+
97+
if (httpGraphQLResponse.body.kind === 'complete') {
98+
res.send(httpGraphQLResponse.body.string);
99+
return;
100+
}
102101

103-
for await (const chunk of httpGraphQLResponse.body.asyncIterator) {
104-
res.write(chunk);
105-
// Express/Node doesn't define a way of saying "it's time to send this
106-
// data over the wire"... but the popular `compression` middleware
107-
// (which implements `accept-encoding: gzip` and friends) does, by
108-
// monkey-patching a `flush` method onto the response. So we call it
109-
// if it's there.
110-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
111-
if (typeof (res as any).flush === 'function') {
112-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
113-
(res as any).flush();
114-
}
115-
}
116-
res.end();
117-
})
118-
.catch(next);
102+
for await (const chunk of httpGraphQLResponse.body.asyncIterator) {
103+
res.write(chunk);
104+
// Express/Node doesn't define a way of saying "it's time to send this
105+
// data over the wire"... but the popular `compression` middleware
106+
// (which implements `accept-encoding: gzip` and friends) does, by
107+
// monkey-patching a `flush` method onto the response. So we call it
108+
// if it's there.
109+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
110+
if (typeof (res as any).flush === 'function') {
111+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
112+
(res as any).flush();
113+
}
114+
}
115+
res.end();
119116
};
120117
}

0 commit comments

Comments
 (0)