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

Serverless API离线测试:Post请求MongoDB触发字段验证错误

问题分析与解决方案

核心问题

触发验证错误的原因很明确:请求体解析方式错误。你通过Postman发送的是Content-Type: application/json格式的请求,但在handler中使用了querystring.decode()——这个方法仅适用于解析application/x-www-form-urlencoded类型的表单数据,对JSON字符串解析后会得到空对象或undefined的字段,导致mongoose无法获取到name、email、password的值,触发必填字段验证失败。

另外还有一个潜在问题:你的User Schema中未定义apiKey字段,即使解析成功,这个字段也不会被存入MongoDB,需要补充到schema中。

具体修改步骤

1. 替换请求体解析逻辑

把querystring.decode(event.body)替换为JSON.parse(event.body),同时添加异常处理,避免非法JSON请求导致崩溃:

/* Create User*/
module.exports.create = (event, context, callback) => {
  context.callbackWaitsForEmptyEventLoop = false;
  Database.connectToDatabase()
    .then(() => {
      let body;
      try {
        // 解析JSON格式的请求体
        body = JSON.parse(event.body);
      } catch (parseErr) {
        return callback(null, {
          statusCode: 400,
          headers: { "Content-Type": "text/plain" },
          body: "Invalid JSON format in request body",
        });
      }

      console.log(event.body);
      const randomKey = uuidv4();
      let newUser = new User({
        name: body.name,
        email: body.email,
        password: body.password,
        apiKey: randomKey.replace(/-/g, ""),
      });

      newUser.save(function (err, user) {
        if (err) {
          callback(null, {
            statusCode: err.statusCode || 500,
            headers: { "Content-Type": "text/plain" },
            body: err.message,
          });
        } else {
          callback(null, {
            statusCode: 200,
            body: JSON.stringify(user),
          });
        }
      });
    })
    .catch((err) => {
      callback(null, {
        statusCode: err.statusCode || 500,
        headers: { "Content-Type": "text/plain" },
        body: err.message,
      });
    });
};

2. 补充User Schema中的apiKey字段

在你的mongoose Schema中添加apiKey字段,确保它能被存入数据库:

const userSchema = new mongoose.Schema(
  {
    email: {
      type: String,
      trim: true,
      required: true,
      unique: true,
      validate(value){
        if(!validator.isEmail(value)){
          throw new Error ("Please enter correct email");
        }
      }
    },
    name: {
      type: String,
      trim: true,
      required: true,
    },
    password: {
      type: String,
      required: true,
    },
    // 新增apiKey字段
    apiKey: {
      type: String,
      required: true,
      unique: true,
    },
    salt: String,
    role: {
      type: String,
      default: "Normal",
    },
    created: {
      type: "Date",
      default: Date.now,
    },
    subscription: {
      type: String,
      default: "dev",
    },
    token: {
      type: String,
      default: "free",
    },
  }, { collection: "Users" } // 修正原代码括号位置的语法错误
);

userSchema.post("save", function (_doc, next) {
  _doc.password = undefined;
  return next();
});

3. 可选:验证请求头的Content-Type

为了更严谨,可以在handler开头检查Content-Type是否为application/json,拒绝不符合格式的请求:

// 在Database.connectToDatabase()之前添加
if (!event.headers || event.headers['Content-Type'] !== 'application/json') {
  return callback(null, {
    statusCode: 415,
    headers: { "Content-Type": "text/plain" },
    body: "Unsupported Media Type: Only application/json is accepted",
  });
}

测试验证

修改完成后,用你提供的curl请求再次测试,应该能成功创建用户并将数据(包括apiKey)存入MongoDB,返回200状态码和用户信息(password字段会被post-save钩子移除)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 21:15:36