我正在使用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;