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 }] }
}
};
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
andpassword
in thosectx.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.