'KoaJs cant handle POST requests on CloudFunctions
I have a NodeJS Application written in KoaJS,
app.ts
const app = new Koa();
app.use(healthCheck());
app.use(bodyParser());
app.use(errorHandler());
app.use(endpoints);
export default app;
main.ts
const port = process.env.PORT || 3000;
if (!isCloudFunctions()) {
app
.listen(port, () => {
console.info(`Listening at http://localhost:${port}`);
})
.on('error', console.error);
}
export const api = (req, res) => {
app.callback()(req, res);
}
The app works well on Cloud Runs
,
I can deploy the app on Cloud Functions
, but on Functions
the app can only handle GET
requests.
If I try a POST request, I get this error
InternalServerError: stream is not readable
at getRawBody (/workspace/node_modules/raw-body/index.js:112:10)
at readStream (/workspace/node_modules/raw-body/index.js:178:17)
at AsyncFunction.module.exports [as json] (/workspace/node_modules/co-body/lib/json.js:39:21)
at executor (/workspace/node_modules/raw-body/index.js:113:5)
at parseBody (/workspace/node_modules/koa-bodyparser/index.js:100:26)
at new Promise (<anonymous>)
at bodyParser (/workspace/node_modules/koa-bodyparser/index.js:85:25)
at next (/workspace/node_modules/koa-compose/index.js:42:32)
at /workspace/webpack:/sample-explore/apps/sample-api/src/middlewares/health-check.ts:10:12
at Generator.next (<anonymous>)
I re-created the application in ExpressJS, and it works fine with both Runs and Functions
However I am really like the native async/await
, compose routing
of KoaJS
Does anyone know the reason why KoaJS can not handle POST requests on Cloud Functions?
Solution 1:[1]
The json body is automatically parsed in google cloud functions (documentation) and the koa-bodyparser
middleware can't handle already parsed bodies.
More info on this issue: https://github.com/koajs/bodyparser/issues/127
Suggested fixes, from the issue thread, are to either use ctx.req.body
instead of ctx.request.body
, you'll need to parse it when running locally of course.
Alternatively add a middleware that will support already parsed bodies.
function hybridBodyParser (opts) {
const bp = bodyParser(opts)
return async (ctx, next) => {
ctx.request.body = ctx.request.body || ctx.req.body
return bp(ctx, next)
}
}
app.use(hybridBodyParser())
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | TetsuBo |