Skip to content

Commit

Permalink
fix: mutation hang when data stream consumed by parser
Browse files Browse the repository at this point in the history
- fixes body parsing issue raised here: #24
- data stream gets consumed by body parser
- changed middleware to look for parsed body and make available where trpc expects it
  • Loading branch information
BlairCurrey committed Mar 12, 2024
1 parent 0785b45 commit f1c5bae
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 213 deletions.
40 changes: 2 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,45 +99,9 @@ const adapter = createKoaMiddleware({
});
```

## With a Koa Body Parser:
# Note About Using With a Body Parser:

Body parsing middleware such as [`@koa/bodyparser`](https://github.com/koajs/bodyparser) and [`koa-bodyparser`](https://www.npmjs.com/package/koa-bodyparser) consume the raw body on requests which tRPC expects. If this middleware is added to koa after one of these body parsers, or the body is otherwise consumed before this middleware, then tRPC may unexpectedly fail to handle requests (such as tRPC mutation requests hanging). This matter was originally discussed in [this GitHub issue](https://github.com/BlairCurrey/trpc-koa-adapter/issues/24).

If using `@koa/bodyparser` or `koa-bodyparser`, you can resolve this in either of the following ways:

- Add the `createKoaMiddleware` before the body parser, if this otherwise works for you
- Use `@koa/bodyparser` or `koa-bodyparser`'s `disableBodyParser` option to disable the body parser for the trpc routes:

```ts
const prefix = '/trpc';
const app = new Koa();

app.use(async (ctx, next) => {
if (ctx.path.startsWith(prefix)) ctx.disableBodyParser = true;
await next();
});
app.use(bodyParser());
app.use(
createKoaMiddleware({
router: appRouter,
prefix,
})
);
```

For `@koa/bodyparser` only, you can use the [`patchNode` option](https://github.com/koajs/bodyparser?tab=readme-ov-file#options) to patch the body on the request, which tRPC can use instead of the raw body:

```ts
const app = new Koa();
app.use(bodyParser({ patchNode: true }));
app.use(
createKoaMiddleware({
router: appRouter,
prefix,
})
);
```
Using a bodyparser such as [`@koa/bodyparser`](https://github.com/koajs/bodyparser), [`koa-bodyparser`](https://www.npmjs.com/package/koa-bodyparser), or otherwise parsing the body will consume the data stream on the incoming request. To ensure that tRPC can handle the request, this library looks for the parsed body on `ctx.request.body`, which is where `@koa/bodyparser` and `koa-bodyparser` store the parsed body. If for some reason the parsed body is being stored somewhere else, and you need to parse the body before this middleware, the body will not be available to tRPC and mutations will fail.

# Development

Expand Down
24 changes: 24 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ import {
import { Middleware } from 'koa';
import { IncomingMessage, ServerResponse } from 'http';

declare module 'koa' {
interface Request {
/* eslint-disable @typescript-eslint/no-explicit-any */
body?: any;
}
}
declare module 'http' {
interface IncomingMessage {
/* eslint-disable @typescript-eslint/no-explicit-any */
body?: any;
}
interface ServerResponse {
/* eslint-disable @typescript-eslint/no-explicit-any */
body?: any;
}
}

export type CreateTrpcKoaContextOptions = NodeHTTPCreateContextFnOptions<
IncomingMessage,
ServerResponse<IncomingMessage>
Expand All @@ -27,6 +44,13 @@ export const createKoaMiddleware =

if (prefix && !request.path.startsWith(prefix)) return next();

// put parsed body (by koa-bodyparser/@koa/bodyparser for example)
// where nodeHTTPRequestHandler will look for it.
// https://github.com/BlairCurrey/trpc-koa-adapter/issues/24
if ('body' in request) {
req.body = request.body;
}

// koa uses 404 as a default status but some logic in
// nodeHTTPRequestHandler assumes default status of 200.
// https://github.com/trpc/trpc/blob/abc941152b71ff2d68c63156eb5a142174779261/packages/server/src/adapters/node-http/nodeHTTPRequestHandler.ts#L63
Expand Down
Loading

0 comments on commit f1c5bae

Please sign in to comment.