上下文
我正在尝试使用restify
(2.6.2)构建一个动态服务器,在服务器启动后要安装和卸载服务。我意识到这可以被视为奇怪的东西,但它在面向DSL
的项目的背景下有意义。为了实现这一目标,我实现了以下功能:
var install = function (path, method, handler) {
var id = server[method](path, function (request, response) { // [1]
handler (request, response);
});
return id;
}
var uninstall = function (id) {
delete server.routes[id]; // [2]
}
安装功能,在路径和方法名称[1]指定的路径中安装处理程序。卸载功能,通过从路由[2]中删除处理程序来卸载处理程序。此功能通过以下代码公开为服务:
var db = ...
var server = restify.createServer ()
.use (restify.bodyParser ({ mapParams: false }))
.use (restify.queryParser ())
.use (restify.fullResponse ());
service.post ('/services', function (request, response) {
var path = request.body.path;
var method = request.body.method;
var handler = createHandler (request.body.dsl) // off-topic
var id = install (path, method, handler)
db.save (path, method, id); // [3]
});
service.del ('/services', function (request, response) {
var path = request.body.path;
var method = request.body.method;
var id = db.load (path, method); // [4]
uninstall (id);
});
在post方法[3]中,从body获取处理程序(它是如何进行的主题),并且安装了一个服务,将返回的id存储在数据库中。 del方法[4],从数据库中检索id并调用卸载函数。
问题
此代码已经过单元测试并且工作正常但是当我尝试执行如下所示的安装/卸载序列时会出现故障。在此示例中,请假设所有请求的正文包含相同的path
,http verb
和正确的内容,以构建正确的handler
:
/*
post: /services : Installed -> ok
del: /services : Resource not found -> ok
post: /services : Resource not found -> Error :(
*/
在第一次安装中,handler
在通过path
和verb
加入资源时执行。正确履行了卸载请求,因为在Resource not found
访问path
时获得了verb
消息。然而,当第二个在服务器中安装相同的主体时,Resource not found
加入path
时会返回verb
。
我认为错误在[2]中,因为可能是,我没有使用restify
的正确取消注册策略。
问题
一旦服务器启动,如何有效地从restify
删除处理程序?
答案 0 :(得分:4)
在查看了解析源之后,我发现了以下内容,您可能想要尝试而不是简单地“删除”(https://github.com/restify/node-restify/blob/master/lib/server.js)。
/*
* Removes a route from the server.
* You pass in the route 'blob' you got from a mount call.
* @public
* @function rm
* @throws {TypeError} on bad input.
* @param {String} route the route name.
* @returns {Boolean} true if route was removed, false if not.
*/
Server.prototype.rm = function rm(route) {
var r = this.router.unmount(route);
if (r && this.routes[r]) {
delete this.routes[r];
}
return (r);
};