Home > OS >  Getting empty ctx.body on post requests in Koajs
Getting empty ctx.body on post requests in Koajs

Time:04-11

I'm new to Koa. I wrote a simple api server with it. I have used "koa-bodyparser" and i have added content-type: application/json to the request header, but i still get empty request body on post requests. Could anyone please guide me?

this is my server.js

const Koa = require('koa');
const bodyParser = require('koa-bodyparser')();
const compress = require('koa-compress')();
const cors = require('@koa/cors')();
const helmet = require('koa-helmet')();
const logger = require('koa-logger')();

const errorHandler = require('./middleware/error.middleware');
const applyApiMiddleware = require('./api');
const { isDevelopment } = require('./config');
const db = require('./db/db');

const server = new Koa();

db.connectDB();

/**
 * Add here only development middlewares
 */
if (isDevelopment) {
  server.use(logger);
}

/**
 * Pass to our server instance middlewares
 */
server
  .use(errorHandler)
  .use(helmet)
  .use(compress)
  .use(cors)
  .use(bodyParser);

/**
 * Apply to our server the api router
 */
applyApiMiddleware(server);

module.exports = server;

and this is my endpoint:

router.post('/', controller.createOne);

and the createone method:

 exports.createOne = async ctx => {
 console.log(ctx.body);
 ctx.assert(username, 400, 'Username is required');
 ctx.assert(password, 400, 'Password is required')
 try {
   const { name, username, password } = ctx.request.body;

    let user = await User.findOne({ username });

    if (user){
      ctx.status = 400;
      ctx.body = { errors: [{ msg: 'User already exists' }] };
    }

    user = new User({
      name,
      username,
      password
    });

    const salt = await bcrypt.genSalt(10);

    user.password = await bcrypt.hash(password, salt);

    await user.save();

    user.password = undefined;

    ctx.status = 201;
    ctx.body = user;

  } catch (error) {
    console.error(error.message);
    ctx.status = 500;
    ctx.body = { errors: [{ msg: error.message }] }
 }
};

and the postman request: enter image description here

CodePudding user response:

You are confusing ctx.body with ctx.request.body, at least in your log statement (in the destructured assignment it is actually correct).

ctx.body is the same as ctx.response.body, it's the response body which is empty because you didn't set it yet.

ctx.request.body is the request body which you actually want.


Some other issues I noticed:

  • You use username and password in those ctx.assert lines before they are defined.

  • In your duplicate user case, you forgot to return from your function, so the rest of the function will still run and even with an existing user you will create a new one.


Since you seem to be working on debugging that error 500: A little tip, error.message is quite useless for debugging as it's missing the stack (most importantly - since this is what shows you where exactly the error came from) and the error class, code and other properties. If you use console.error, always log the whole error object and not just the message: console.error(error). If you want to prepend some text, don't use concatenation, use separate arguments instead, so the object is still formatted: console.error('Error in request:', error).

If you need a string (for example when returning it as response, which you should do only in development mode by the way because you don't want to expose your inner workings to potential attackers), use error.stack and not error.message, because it will contain a lot more information.

  • Related