Node.js+Express+MongoDB构建REST API时model.save()返回无效输出排查
Hey Adnan, 我看了你的代码和问题描述,马上就发现几个关键问题导致你保存用户后只拿到_id和__v,而没有实际的用户数据。咱们一步步来解决:
1. Body-parser 中间件加载顺序错误
在你的App.js里,你把body-parser的配置放在了routes(app)之后,这会导致路由处理请求的时候,body-parser还没生效,req.body自然是空的!必须把中间件的加载放在路由之前。
修改后的App.js:
var routes= require('./src/routes/userRoutes').routes var express= require("express") var mongoose=require('mongoose') var bodyParser=require('body-parser') const app = express(); const PORT=4001 // 先加载body-parser,确保路由能解析请求体 app.use(bodyParser.urlencoded({extended:true})); app.use(bodyParser.json()); // 首页路由 app.get('/',function(req,res){ res.send(`Node and express server running on PORT ${PORT}`); }); // 连接数据库 mongoose.Promise= global.Promise; mongoose.connect('mongodb://localhost/userdb', { useNewUrlParser:true, useUnifiedTopology:true }) // 加载路由(必须在body-parser之后) routes(app) // 启动服务器 app.listen(PORT,function(){ console.log(`Your server is running on PORT ${PORT}`); });
2. 路由配置错误:POST请求放错了位置
你把创建用户的POST请求挂在了/users/:userID这个路由下,这明显不对——:userID是用来定位已存在用户的(比如修改、删除),创建新用户应该用/users的POST请求。另外你还写错了参数名:req.params.donationID应该是req.params.userID。
修改后的userRoute.js:
var addNewUser = require('../controllers/userController').addNewUser; const routes = (app) => { app.route('/users') .get((req,res)=> res.send("Get request successful")) .post(addNewUser); // 创建用户的POST放在这里 app.route('/users/:userID') .put((req,res)=>res.send(`Put Request succesful for ${req.params.userID}`)) .delete((req,res)=>res.send("delete Request successful")); app.route('/done') .get((req,res)=>{ res.send("Goodbye"); process.exit(0); }); } module.exports={routes};
3. 请求方式错误:用URL参数而非请求体传递数据
你发送的请求是localhost:4001/users/1?userName=Adnan&UserID=123&password=0000,这里的参数是放在URL查询字符串里的,而你的代码里new UserModel(req.body)是从请求体拿数据的,两者不匹配!
创建用户应该用请求体传递数据,比如用Postman或者curl发送:
curl -X POST -H "Content-Type: application/json" -d '{"userName":"Adnan","UserID":123,"password":"0000"}' http://localhost:4001/users
另外注意你的模型里字段是UserID(大写U),如果请求里写成userId小写,会导致字段不匹配,数据存不进去。建议统一用小驼峰命名(比如userId),更符合JavaScript的编码习惯,修改userModel.js:
var mongoose = require('mongoose') const Schema = mongoose.Schema; const UserSchema = new Schema({ userName: { type: String, //required:"Enter your name", }, userId: { // 改成小驼峰 type: Number, //required:"Enter User ID:", }, password: { type: String, // required:"Enter your password?", // 之前拼写错误reequired,修正一下 } }); module.exports={UserSchema}
4. 调试小技巧
可以在addNewUser里打印req.body,确认数据是否正确接收:
const addNewUser = (req,res) => { console.log('Received request body:', req.body); // 打印请求体 let newUser= new UserModel(req.body); newUser.save((err,user) => { if(err) res.send(err) else res.json(user) }) }
做完这些修改后,重新启动服务器,发送正确的POST请求,就能返回包含完整用户数据的JSON对象了!
内容的提问来源于stack exchange,提问作者Adnan Ahmed

