Express subpath GET returns 404 with no content

Express subpath GET returns 404 with no content

我正在处理一个 Express + MongoDB (w/Mongoose) 项目的采访,我需要为其添加一个端点。

端点是 GET /listings/ranking,我应该在其中列出所有产品并按销售数量降序排列。我在 server/api/listing/index.js 文件中写了端点(只有那个端点,另一个已经存在):

var controller = require("./listing.controller");
var config = include("config/environment");
var router = express.Router();

var { route } = require("endpoint-handler")(router)

route.get("/", controller.getAll);

route.get("/:listing_id", controller.getOne);

route.get("/ranking", controller.getMostSold);

module.exports = router;

控制器(server/api/listing/listing.controller)中getMostSold的代码:

var Listing = require("./listing.model");

exports.getAll = (req, res) => Listing.find({});

exports.getOne = (req, res) => Listing.findOne({
    listing_id: req.params.listing_id
  })
  .then(listing => {
    if (!listing) {
      throw { name: "NotFound", statusCode: 404 };
    }
    return listing;
  });

exports.getMostSold = (req, res) => {
  var defaultLimit = 3;
  Listing.find({})
    .sort('-quantity')
    .limit(req.query.limit || defaultLimit);
};

以及server/api/listing/router.spec.js中对应的规范:

var should = require("chai").should();
var request = require('supertest');
var app = include('app').app;
var Listing = require('./listing.model');

describe('Listing', () => {
  var samsung = {...};

  beforeEach((done) => {
    return Listing.create(samsung, done);
  });

  describe('GET /listings', function() {
    it('should return all the listings', (done) => {
      request(app).get('/listings').expect(200, [samsung], done);
    });
  });

  describe('GET /listings/:listing_id', function() {

    it('should return the requested listing', (done) => {
      request(app).get('/listings/MLA1111').expect(200, samsung, done);
    });

    it('should return 404 Not Found when the requested listing does not exist', (done) => {
      request(app).get('/listings/WRONGID').expect(404, done);
    });

  });

  describe('GET /listings/ranking', function() {
    var motoG = {...};
    var onePlus = {...};
    var iPhone = {...};
    Listing.create(motoG);
    Listing.create(onePlus);
    Listing.create(iPhone);

    it('should return the top 3 most sold listings since monitoring started', (done) => {
      request(app).get('/listings/ranking').expect(200, [samsung, motoG, onePlus, iPhone], done);
    });

    it('should return the top N most sold listings since monitoring started', (done) => {
      var topN = 2;
      request(app).get(`/listings/ranking?limit=${topN}`).expect(200, [motoG, samsung], done);
    });
  });

我端点的两个规范都失败了,而另一个却工作正常。并不是他们返回了其他东西,他们只是 除了一个空的 404 之外根本没有返回任何东西。我尝试将端点的控制器代码更改为 Listing.find({}),就像 .getAll 方法一样,但它仍然返回 {}.

根据我刚才所说的,我怀疑这只是一个路由问题。即使我更改了代码,它也好像没有识别出一个名为 /listings/ranking.

的端点

这是 server/routes.js 文件以防万一:

var errors = require("./components/errors");

module.exports = (app) => {
  app.use("/listings", require("./api/listing"));
  app.route("/:url(api|components|app|bower_components|assets)/*").get(errors[404]);
};

项目结构如下:

免责声明: 首先,我 post 提出问题的方式是没有所有文件中的所有代码,因为我认为这会使 post 的端点和测试变得混乱,而这些端点和测试不会影响我的。现在问题有了另一个端点,这是造成问题的原因:GET /listings/:listing_id.

显然在 Express 中端点定义的顺序很重要所以发生的事情是我的测试试图解释 GET /listings/ranking 就好像 ranking listing_id 只是因为 /:listing_id 是在它之前定义的。所以它返回 404,因为不存在 ID 为“ranking”的列表。