Express4路由问题

时间:2017-04-23 07:25:35

标签: node.js express routing

我正在使用router.param()在检测到特定参数时加载资源实例:

table.route.js

import express from 'express';
import validate from 'express-validation';
import paramValidation from '../../../config/param-validation';
import tableCtrl from '../controllers/table.controller';
const router = express.Router(); 
router.route('/:tableId')
   /** GET /api/tables/:tableId - Get table */
  .get(tableCtrl.get)

  /** PUT /api/tables/:tableId - Update table */
  .put(validate(paramValidation.updateTable), tableCtrl.update)

  /** DELETE /api/tables/:tableId - Delete table */
  .delete(tableCtrl.remove);

/** Load table when API with tableId route parameter is hit */
router.param('tableId', tableCtrl.load);

export default router;

table.controller.js

import Table from '../../models/table.model';
function load(req, res, next, id) {
  Table.get(id)
    .then((table) => {
      req.table = table; // eslint-disable-line no-param-reassign
      return next();
    })
    .catch(e => next(e));
}

function get(req, res) {
  return res.json(req.table);
}
export default { load, get, ... };

这项工作很好......但是,我需要添加另一条路线来从Table模型中仅获取 meta 对象

table.model.js

const TableSchema = new mongoose.Schema({
  meta: {...},
  columns: [{ ....}]
});

所以我可以使用' meta '添加以下路径作为路径参数

router.route('/:tableId/meta')
   /** GET /api/tables/:tableId - Get table */
  .get(tableCtrl.get)

因为'meta'是:tableId param之后的路径参数,我怎么能避免执行tableCtrl.load函数,而是执行另一个像tableCtrl.loadMeta

router.param('tableId',tableCtrl.load); router.param('tableId / meta',tableCtrl.loadMeta); < =这当然是错误的

感谢您的反馈

更新1

我正在尝试这种方式,但也许还有更好的方法?

router.param('tableId', (req, res, next) => {
  const path = url.parse(req.originalUrl).pathname;
  const lastpart = path.substr(path.lastIndexOf('/') + 1);
  if (lastpart === 'meta') {
    console.log('GOT IT', lastpart);
    tableCtrl.loadMeta(req, res, next);
  } else {
    tableCtrl.load(req, res, next);
  }
  next();
});

更新2 见robertklepp评论

删除下一个(e);在router.param()块中有效地引发了un error

1) ## Table APIs # GET /api/v1/tables/:tableId/meta should get table meta:
     TypeError: Cannot convert undefined or null to object
      at server/v1/tests/table.test.js:120:18
      at tryCatcher (node_modules/bluebird/js/release/util.js:16:23)
      at Promise._settlePromiseFromHandler (node_modules/bluebird/js/release/promise.js:512:31)
      at Promise._settlePromise (node_modules/bluebird/js/release/promise.js:569:18)
      at Promise._settlePromise0 (node_modules/bluebird/js/release/promise.js:614:10)
      at Promise._settlePromises (node_modules/bluebird/js/release/promise.js:693:18)
      at Async._drainQueue (node_modules/bluebird/js/release/async.js:133:16)
      at Async._drainQueues (node_modules/bluebird/js/release/async.js:143:10)

在具有:tableId参数的所有路由中,模型get id被调用两次...一个用于:tableId,另一个用于:tableId / meta

    # GET /api/v1/tables/:tableId/meta
    model get id:  58fda13882be03c9999ba7ef
    route param:  meta
    model get id:  58fda13882be03c9999ba7ef
          1) should get table meta

我的table.router.js文件出错了,经过检查,我可以看到我忘了删除原来的router.param()行...在以下文件中看到它

table.router.js

import express from 'express';
import validate from 'express-validation';
import paramValidation from '../../../config/param-validation';
import tableCtrl from '../controllers/table.controller';

const url = require('url');

const router = express.Router(); // eslint-disable-line new-cap

router.route('/')
   /** GET /api/tables - Get list of tables */
  .get(tableCtrl.list)

  /** POST /api/tables - Create new table */
  .post(validate(paramValidation.createTable), tableCtrl.create);

router.route('/meta')
/** GET /api/tables - Get list of all tables meta */
  .get(tableCtrl.list);

router.route('/columns')
/** GET /api/tables - Get list of all tables meta */
  .get(tableCtrl.list);

router.route('/:tableId/meta')
  /** GET /api/tables/meta - Get table meta */
  .get(tableCtrl.get);

router.route('/:tableId/columns')
/** GET /api/tables/meta - Get table meta */
  .get(tableCtrl.get);

router.route('/:tableId')
   /** GET /api/tables/:tableId - Get full table */
  .get(tableCtrl.get)

  /** PUT /api/tables/:tableId - Update full table */
  .put(validate(paramValidation.updateTable), tableCtrl.update)

  /** DELETE /api/tables/:tableId - Delete full table */
  .delete(tableCtrl.remove);

/** Load table when API with tableId route parameter is hit */
router.param('tableId', tableCtrl.load); <===== SHOULD BE DELETED !!

router.param('tableId', (req, res, next, tableId) => {
  const path = url.parse(req.originalUrl).pathname;
  const lastpart = path.substr(path.lastIndexOf('/') + 1);
  if (lastpart === 'meta') {
    console.log('route param: ', lastpart);
    tableCtrl.loadMeta(req, res, next, tableId);
  } else if (lastpart === 'columns') {
    console.log('route param: ', lastpart);
    tableCtrl.loadColumns(req, res, next, tableId);
  } else {
    console.log('route param: ', lastpart);
    tableCtrl.load(req, res, next, tableId);
  }
  // next();
});

export default router;

0 个答案:

没有答案