如何用restify.js处理深层复杂的数据结构

我已经看到了Restify的例子,其中所有的端点位于root:/ users,/ data等。我知道可以像这样实现嵌套:

server.get('/users/:user/data/:id', returnData); 

而req.paramsvariables将具有所有的请求参数。 例:

 { user: '45', id: '80' } 

这似乎工作正常,如果我的应用程序有几个端点,但如果我有一个深度和分支的数据结构,我想通过REST API公开? 就像是:

 { stuff: { points: { colors: { shinyThings: {}, dullThings: {} } }, ships: { enterprises: {}, starDestroyers: {} } }, things: {}, } 

不得不手写所有这些端点的path似乎并不正确。 我结束了很多的path定义和这样的东西:

 server.put('/stuff/:stuff/points/:points/colors/:colors/shinyThings/:shinyThings', returnShinyThing); 

Restify有没有更简单的方法?

我想出了一个办法,虽然我确信有更好的select:

1)创build模块来处理端点上的某些操作。 这些模块将被要求进入中央路由器模块。 示例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)像这样创build一个表示数据结构的对象:

 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服务器对象来附加路由。 在初始化期间,recursion函数_actions模式对象,当find_actions关键字时,它会调用第二个函数,将给定path上的路由处理程序附加到给定的服务器对象上:

 (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()函数)。 因为我删除了非关键部分的function,所以它也有点简化了,但它应该是完全正常的。

这个灵感来自于快递资源的使用方式,尽pipe它并不像使用过程那样精致和简单。