我正在构建API,并尝试允许用户过滤'使用任何参数组合的结果集。
我们有2只猫,每只有4个属性:名称,年龄,性别和颜色。< / p>
cat1 = {'name': 'Fred', 'age': '10', 'sex': 'male', 'color': 'white'}
cat2 = {'name': 'Alex', 'age': '10', 'sex': 'male', 'color': 'black'}
我希望单一路由匹配用户选择应用于其搜索的参数的任意组合。例如,路线将匹配以下(以及任何其他组合):
router.get('/name/:name/age/:age/sex/:sex/color/:color', ...){}
router.get('/name/:name/age/:age/sex/:sex', ...){}
router.get('/age/:age/color/:color', ...){}
基本上,所有参数都是可选的。
我认为正则表达式是最好的方法 - 我怎么能这样做?
答案 0 :(得分:1)
执行此操作的方法是使用正则表达式来解析完整URI并提取搜索条件。 标准订单是免费的。
要提取参数的值,我使用以下正则表达式:
\/
paramName \/([^\/]+)(\/|$)
<强>解释强>
\/
paramName \/
:在斜杠之间匹配给定的参数名称
([^\/]+)
:匹配斜线以外的任何内容(这是我们的值)
(\/|$)
:以斜线或行尾结束
这是一个有效的 JavaScript代码段:
/**
* Extract the value of a param inside a path
* Path format should match this pattern : /p1/p1value/p2/p2Value/pX/pXValue
* @param {string} path The path
* @param {string} param The param name
*/
function getParamValue(path, param) {
var re = new RegExp('\/'+ param + '\/([^\/]+)(\/|$)');
var matches = re.exec(path);
if(matches && matches.length) {
return matches[1];
}
}
// Define possible criteria
var criteria = ['name', 'age', 'sex', 'color', 'dummy'];
// Let's play with some sample paths
var paths = [
"/name/mcfly/age/42/sex/male/color/blue",
"/sex/male/name/color/blue/mcfly/age/42",
"/sex/male",
"/color/black/name/kitty"
];
// For each path, display criteria and associated values
paths.forEach(function(path) {
console.log("path=", path);
criteria.forEach(function(criterion) {
console.log(criterion + '=' + getParamValue(path, criterion));
});
console.log("------------------------");
});
此外,还有一个示例 Express app:
<强> utils.js 强>
module.exports = {
getParamValue: function (path, param) {
var re = new RegExp('\/'+ param + '\/([^\/]+)(\/|$)');
var matches = re.exec(path);
if(matches && matches.length) {
return matches[1];
}
}
}
搜索-service.js 强>
var utils = require('./utils');
module.exports = {
getSearchCriteria: function(path) {
var criteria = [];
['name', 'age', 'sex', 'color'].forEach(function(criterion) {
var value = utils.getParamValue(path, criterion);
if(value) {
criteria.push({"criterion": criterion, "value": value});
}
});
return criteria;
},
search: function(criteria) {
return "search using the following criteria", JSON.stringify(criteria, null, 2);
}
}
<强> app.js 强>
var express = require('express');
var app = express();
var searchService = require('./search-service');
var port = 7357;
app.get('/api/search/*', function(req, res, next) {
var criteria = searchService.getSearchCriteria(req.originalUrl);
var result = searchService.search(criteria);
res.send("<!doctype html><html><body><pre>" + result + "</pre></body></html>");
});
// start server
app.listen(port, function() {
console.log('Server listening on port %d', port);
});
运行node app
然后测试一些网址:
http://localhost:7357/api/search/name/mcfly/age/42/sex/male/color/blue
http://localhost:7357/api/search/sex/female/color/orange/name/judith/age/25
http://localhost:7357/api/search/color/green
并检查页面内容