Node.JS:处理GET和POST请求。

3

我正在学习Node.JS,并且作为练习,需要创建两个端点:

  1. GET /albums - 获取数据库中所有专辑的列表
  2. POST /purchases - 创建购买记录

我的尝试如下:

const mongoose = require('mongoose');
const express = require('express');
const app = express();
const bodyParser = require('body-parser');

// Imports
const Album = require("./models/album");
const Purchase = require("./models/purchase");

// TODO code the API

// Connect to DB
mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true});
var conn = mongoose.connection;
conn.on('connected', function() {
    console.log('database is connected successfully');
});
conn.on('disconnected',function(){
    console.log('database is disconnected successfully');
})
conn.on('error', console.error.bind(console, 'connection error:'));

// Routes
app.get('/albums', function(req, res, next) {
    Album.find({}, (err, albums) => {
        if (!err) {
          res.set({
            'Content-Type': 'application/json',
            'Status': 200,
          })
          return res.end(JSON.stringify(albums));
        } else {
            console.log('Failed to retrieve the Course List: ' + err);
        }
    });
 
});

// POST method route
app.post('/purchases', (req, res) => {
  const purchase = new Purchase({
    user: req.body.user,
    album: req.body.album
  })
  
  purchase.save(function (err, post) {
    if (err) { return err }
    res.json(201, purchase);
  })
  
})

module.exports = app;

GET请求说明:

  1. 由于这是一个JSON API,除了destroy方法需要返回204状态码表示无内容外,其他情况应该返回JSON和200状态码。

  2. 对于GET、POST和PUT方法,应在数据对象中返回所有三个专辑列标题、表演者和成本。下面是response.body.data的格式示例:

预期格式:

response.body.data = {
  _id: "the id of the album",
  title: "Appetite for Destruction", 
  performer: "Guns N' Roses", 
  cost: 20
};

POST请求的指令:

  1. /purchases路由应该在请求体中设置用户和专辑属性。然后,它应该将对这些记录的引用存储在新创建的购买记录上。

  2. POST /purchases的响应应该包括购买记录以及用户和专辑关系,这些关系应该填充所有的数据字段。

专辑模式:

const albumSchema = mongoose.Schema({
  performer: String,
  title: String,
  cost: Number
});

购买模式:
const purchaseSchema = mongoose.Schema({
  user: {type: mongoose.Schema.Types.ObjectId, ref: "User"},
  album: {type: mongoose.Schema.Types.ObjectId, ref: "Album"}
})

该程序需要通过以下两个端点的测试用例:
describe("GET /albums", () => {
    it("should return an array of all models", async () => {
      const album = new Album(albumData).save();
      const res = await chai
        .request(app)
        .get("/albums")
      ;
      expect(res.status).to.equal(200);
      expect(res).to.be.json;
      expect(res.body.data).to.be.a("array");
      expect(res.body.data.length).to.equal(1);
      expect(res.body.data[0].title).to.equal(albumData.title);
      expect(res.body.data[0].performer).to.equal(albumData.performer);
      expect(res.body.data[0].cost).to.equal(albumData.cost);
    }).timeout(2000);
  });

describe("POST /purchases", () => {
    it("should create a new purchase and return its relations", async () => {
      const otherAlbumData = {
        title: "Sample",
        performer: "Unknown",
        cost: 2,
      };
      const album = await new Album(otherAlbumData).save();
      const user = await new User({name: "James"}).save();
      const res = await chai
        .request(app)
        .post("/purchases")
        .send({user, album})
      ;
      expect(res.status).to.equal(200);
      expect(res).to.be.json;
      expect(res.body.data).to.haveOwnProperty("user");
      expect(res.body.data.user).to.haveOwnProperty("name");
      expect(res.body.data).to.haveOwnProperty("album");
      expect(res.body.data.album).to.haveOwnProperty("title");
      expect(res.body.data.user.name).to.equal(user.name);
      expect(res.body.data.album.title).to.equal(album.title);
    }).timeout(2000);
  });
});

问题在于 GET /albums 没有正确地获取数据。错误信息是:"期望未定义为数组",而 POST /purchases 抛出错误 500,"无法读取未定义的 'user' 属性",但是根据描述 "路由应该期望请求体中设置了 user 和 album 属性"。
有人可以给我指点一下吗?我对 Node.JS 还比较新。谢谢。

你尝试过调试吗?在路由器中打印请求内容,在测试中打印响应内容。这样应该能给你一些线索。 - Alex Blex
1个回答

0

Routes之前,您应该添加以下代码:

app.use(express.json({ limit: '15kb' }))
app.use(express.urlencoded({ extended: false }))

仍然出现相同的错误。两个响应都未定义。 - Ashar
你能提供 codesandbox 让我们运行它吗? - Ali Shefaee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接