You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express+Mongoose创建订单时userId必填校验错误求助

POST请求创建订单时Mongoose报ValidationError: userId必填错误

使用Express+Mongoose开发API时,提交POST请求创建订单返回500错误,报错信息为ValidationError: userId: Path userId is required。请求体中已包含顶层的userId字段,但Mongoose无法识别该字段。尝试过提取req.body.order作为参数,此时请求能成功但无法存入userId,还得把Schema里的userId设为非必填,不符合需求。

请求体内容

{
  "order": [
    {
      "item": {
        "id": "p2",
        "title": "Scarf",
        "description": "Red Scarf",
        "price": 8
      },
      "quantity": 2,
      "totalItemCost": 16
    }
  ],
  "userId": "659e15b29fcef318fc03bde8"
}

创建订单控制器代码

export const createOrderController = async (req: express.Request, res: express.Response) => {
    try {
        const order = req.body;
        console.log('order is ' + JSON.stringify(order))
        let createdOrder = await createOrder({
            order
        })
        return res.status(200).json(createdOrder).end();
    }
    catch (error) {
        console.log('Error is ' + error)
        return res.sendStatus(500)
    }
} 

订单Schema与模型代码

const productSchema = new mongoose.Schema({
    id: { type: String, required: true },
    title: { type: String, required: true },
    description: { type: String, required: true },
    price: { type: Number, required: true },
})

const OrderItemSchema = new mongoose.Schema({
    item: { type: productSchema, required: true },
    quantity: { type: Number, required: true },
    totalItemCost: { type: Number, required: true }
})

const OrderSchema = new mongoose.Schema({
    order: { type: [OrderItemSchema], required: true },
    userId: { type: String, required: true }
})

export const OrderModel = mongoose.model('order', OrderSchema);
export const createOrder = (createdOrder: Record<string, any>) => new OrderModel(createdOrder).save().then((order) => order.toObject()) 

问题原因

你在调用createOrder函数时,把整个请求体包裹在了一个order属性里,导致Mongoose接收到的数据结构是{ order: { order: [...], userId: "xxx" } },顶层并没有userId字段,所以触发必填校验失败。

修复方案

直接传入req.body给createOrder函数即可,不需要额外包裹order属性:

export const createOrderController = async (req: express.Request, res: express.Response) => {
    try {
        const orderData = req.body;
        console.log('order data is ' + JSON.stringify(orderData))
        let createdOrder = await createOrder(orderData) // 直接传递请求体
        return res.status(200).json(createdOrder).end();
    }
    catch (error) {
        console.log('Error is ' + error)
        return res.sendStatus(500)
    }
} 

如果不想修改控制器的变量命名,也可以通过展开运算符传递所有属性:

let createdOrder = await createOrder({
    ...order // 展开req.body的所有字段
})

验证

修改后,Mongoose会接收到符合OrderSchema定义的数据结构:包含order数组和顶层userId字段,能正常通过必填校验并保存订单数据。

内容的提问来源于stack exchange,提问作者chucknor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:50:11