Mongoose Express API 未从 req.body 读取

Posted

技术标签:

【中文标题】Mongoose Express API 未从 req.body 读取【英文标题】:Mongoose Express API not reading from req.body 【发布时间】:2021-09-09 10:07:39 【问题描述】:

我目前正在使用 MongoDB (Mongoose) 和 Express 构建应用程序的后端。我正在研究 API,并注意到在测试对 /movies 的 POST 请求时,它没有从 req.body 提交任何信息。当我使用虚拟数据对其进行测试并将信息硬编码到要提交的新电影中时,它可以工作,并且这是唯一发送到数据库的数据。部分代码和示例如下:

这是到movies 的API 路由代码,所有代码都在api.js 文件中找到。

router.get("/movies", (req, res, next) => 
  //this will return all the data, exposing only the id and action field to the client
  Movie.find(, "movie")
    .then((data) => res.json(data))
    .catch(next);
);

router.post("/movies", (req, res, next) => 
  let movie = new Movie();
  movie.name = req.body.name;
  movie.description = req.body.description;
  movie.image = req.body.imageURL;
  movie.date = req.body.date;
  movie.runningTime = req.body.runningTime;
  movie.trailer = req.body.trailer;
  movie.cast = [];
  movie.rating = 0;
  movie.reviews = [];
  movie.meta = 
    likes: 0,
  ;

  console.log(movie);

  movie.save((err, movie) => 
    if (err) return next(err);
    res.status(201);
  );
);

下面是架构和模型:

const Schema = mongoose.Schema;

const movieSchema = new Schema(
  name: String,
  description: String,
  image: String,
  date: Date,
  runningTime: Number,
  trailer: String,
  cast: [type: Schema.Types.ObjectId, ref: 'actor'],
  rating: Number,
  reviews: [
    
      author: String,
      title: String,
      text: String,
      rating: Number,
    ,
  ],
  meta: 
    likes: Number,
  ,
);

const Movie = mongoose.model("movie", movieSchema);

module.exports = Movie;

movie 在发送一个填满所有数据的 POST 请求后的样子:


  meta:  likes: 0 ,
  cast: [],
  _id: 60d6e848d952c95f9ccd4dc8,
  reviews: [],
  rating: 0

这是我的index.js 文件:

const express = require("express");
const mongoose = require("mongoose");
const routes = require("./api/api");
const bodyParser = require("body-parser");
require("dotenv").config();

const app = express();
app.use(express.json());

const port = process.env.PORT || 5000;

// Connect to DB
mongoose
  .connect(process.env.DB,  useNewUrlParser: true, useUnifiedTopology: true )
  .then(() => console.log("Connection to DB was made"))
  .catch((err) => console.error(err));

mongoose.Promise = global.Promise;


// Header stuff makes configuration easier
app.use((req, res, next) => 
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept"
  );
  next();
);

app.use("/api", routes);


app.use((err, req, res, next) => 
  console.log(err);
  next();
);

app.listen(port, () => 
  console.log(`Server running on port $port`);
);

提交的所有数据都不是来自req.body,而是全部硬编码。我不太清楚为什么没有从 req.body 读取任何内容,因此我们将不胜感激!

【问题讨论】:

您可能希望包含(在您的帖子中)正在使用的 html 表单标记。另外,如果您遗漏任何内容,请参阅此Express - req.body。 在 POST 请求的情况下需要一个 body parser 中间件。 目前,您正在使用 express.json() 中间件来解析传入的请求。因此,请求应采用 JSON 格式,否则不会填充 req.body。 【参考方案1】:

你的解析器已经到位,所以应该没问题。请确保您的请求是正确的 JSON。 (欢迎使用客户端或 cURL req 代码)。我建议使用Postman 来测试 HTTP 端点。

我建议您使用带有Joi 验证模块的自定义中间件,以防止发生任何错误。这是我的看法(它是 TypeScript)

import Joi,  ObjectSchema  from "joi";
import  Request, Response, NextFunction  from "express";

export function validate(schema: ObjectSchema): (req: Request, res: Response, next: NextFunction) => unknown 
    return function (req, res, next) 
        const validation = schema.validate(req.body);
        const error = !!validation.error;
        if (error) return res.status(400).json( code: "INVALID_BODY" );
        return next();
    ;

这样使用:

router.get("/path", 
  validate(Joi.object(
    name: Joi.string().required()
    // ...
  )),
  async (req, res) => 
    // Your handler
  
)

至于其他,请允许我给你一些建议。

    根据Mongoose docs,您应该使用带有await Model.find().exec() 之类的promise 的find,而不是await Model.find()。 您应该使用 Mongoose 的 default values 以避免重复! 不要像这样分配新对象的每个属性,尝试:
const movie = new Movie(
  name: req.body.name,
  description: req.body.description,
  // ...
)

【讨论】:

以上是关于Mongoose Express API 未从 req.body 读取的主要内容,如果未能解决你的问题,请参考以下文章

基于用户类型的有条件返回值的结构化节点 API(express、mongodb、mongoose)

部分字符串匹配 - GET 请求 API - Mongoose、Express、Node

如何对使用 Express + Mongoose 构建的 NodeJs REST API 服务器进行单元测试?

如何在 Express 和 Mongoose 的一个控制器 API 内发出多个“查找”请求?

获取 Express API/Mongoose 调用后承诺不触发 .then()

NodeJS Express Mongoose API 的 2018 年 MongoDB 不同计数