Javascript 如何使用restify.js处理深度复杂的数据结构
我见过Restify的示例,其中所有端点都位于根:/users、/data等上。我知道可以像这样实现嵌套:Javascript 如何使用restify.js处理深度复杂的数据结构,javascript,node.js,rest,restify,Javascript,Node.js,Rest,Restify,我见过Restify的示例,其中所有端点都位于根:/users、/data等上。我知道可以像这样实现嵌套: server.get('/users/:user/data/:id', returnData); req.params变量将包含所有请求参数。例如: { user: '45', id: '80' } 如果我的应用程序只有很少的端点,这似乎可以正常工作,但是如果我有一个深度和分支的数据结构,我想通过RESTAPI公开它呢?比如: { stuff: { points: {
server.get('/users/:user/data/:id', returnData);
req.params变量将包含所有请求参数。例如:
{ user: '45', id: '80' }
如果我的应用程序只有很少的端点,这似乎可以正常工作,但是如果我有一个深度和分支的数据结构,我想通过RESTAPI公开它呢?比如:
{
stuff: {
points: {
colors: {
shinyThings: {},
dullThings: {}
}
},
ships: {
enterprises: {},
starDestroyers: {}
}
},
things: {},
}
手动写入所有这些端点的路径似乎并不正确。我最终得到了很多路径定义和类似的东西:
server.put('/stuff/:stuff/points/:points/colors/:colors/shinyThings/:shinyThings', returnShinyThing);
var schema = {
stuff: {
_actions: require('./stuff'),
points: {
_actions: require('./points'),
colors: {
_actions: require('./colors'),
shinyThings: {_actions: require('./shinyThings')},
dullThings: {_actions: require('./dullThings')}
}
},
ships: {
_actions: require('./ships'),
enterprises: {_actions: require('./enterprises')},
starDestroyers: {_actions: require('./starDestroyers')}
}
},
things: {_actions: require('./things')},
}
使用Restify有更简单的方法吗?我想出了一种方法,尽管我确信有更好的替代方法: 1) 创建模块以处理端点上的某些操作。这些模块需要装入中央路由器模块。示例
stuff.js
:
exports.list = function(req, res, next) {
// Code to handle a GET request to /stuff
};
exports.create = function(req, res, next) {
// Code to handle a POST request to /stuff
};
exports.show = function(req, res, next) {
// Code to handle a GET request to /stuff/:id
};
exports.update = function(req, res, next) {
// Code to handle a PUT request to /stuff/:id
};
exports.destroy = function(req, res, next) {
// Code to handle a DELETE request to /stuff/:id
};
2) 在路由器模块中,定义操作->http谓词的映射:
var actions = {
list: 'get',
create: 'post',
show: 'get',
update: 'put',
destroy: 'del'
}
3) 创建一个表示数据结构的对象,如下所示:
server.put('/stuff/:stuff/points/:points/colors/:colors/shinyThings/:shinyThings', returnShinyThing);
var schema = {
stuff: {
_actions: require('./stuff'),
points: {
_actions: require('./points'),
colors: {
_actions: require('./colors'),
shinyThings: {_actions: require('./shinyThings')},
dullThings: {_actions: require('./dullThings')}
}
},
ships: {
_actions: require('./ships'),
enterprises: {_actions: require('./enterprises')},
starDestroyers: {_actions: require('./starDestroyers')}
}
},
things: {_actions: require('./things')},
}
4) 在路由器初始化期间,应用程序向其传递一个Restify服务器对象,以将路由附加到该对象。在初始化过程中,递归函数遍历schema对象,当找到\u actions
键时,它调用第二个函数,将给定路径上的路由处理程序附加到给定的服务器对象:
(function addPathHandlers(object, path) {
for (var key in object) {
if (key === '_actions') addActions(object, path);
else if (typeof object[key] === 'object') {
var single = en.singularize(path.split('/').pop());
if (path.charAt(path.length - 1) !== '/') {
path += ['/:', single, '_id/'].join('');
}
addPathHandlers(object[key], path + key);
}
}
})(schema, '/');
function addActions(object, path) {
// Actions that require a specific resource id
var individualActions = ['show', 'update', 'destroy'];
for (var action in object._actions) {
var verb = actions[action];
if (verb) {
var reqPath = path;
if (individualActions.indexOf(action) !== -1) reqPath += '/:id';
server[verb](reqPath, object._actions[action]);
}
}
}
注意:这利用了模块(即en.singularize()函数)。由于我删除了函数的非关键部分,它也有点简化,但它应该是完全功能的
这方面的灵感来自于对express resource的使用方式的研究,尽管它并没有那么精致和简单