Access the raw body of a request in koa.js

Why we can't use multiple body parser(co-body, koa-body) is because by defination it must prepare ctx.request.body for next middleware to use, this means when a body parser middleware "await next()" to transfer control to next middleware the ctx.req is consumed(or end).

Any body parser middleware for coordination with other request body consumer(one that listen "data" or "end" event on ctx.req), must makesure it "synchronize" listen events(like "data" or "end") on ctx.req. This is not true for co-body and koa-body(use co-body) which do it in "Promise.resolve().then", if "data" or "end" events triggered before one listen these event, data missing(lose "data" event) or error(listen on ended stream) will happen.

@greim is right, but most of the time, we use a high level middleware(such as joi-router) which has force to use a body parser middleware and we have no control, this is still a problem.


It only makes sense to capture the stream once.

You can capture the request body as a string or buffer (I assume this is what you mean by "raw" body) using the raw-body utility, and then keep a reference to it as shown in your own code, such that:

let rawRequestBody = yield rawBody(this.req);
this.rawRequestBody = rawRequestBody;
console.log(typeof this.rawRequestBody); // "string"

Once you do that, don't also use koa-body or co-body, since those are also stream-capturing utilities which assume you haven't yet captured the stream. To make the request body accessible as JSON (for example) simply do this:

this.jsonRequestBody = JSON.parse(this.rawRequestBody);
console.log(typeof this.jsonRequestBody); // "object"