在节点中路由请求和构造响应处理程序

时间:2022-10-13 13:23:58

So I am a systems programmer currently teaching myself web application programming. As is always the case when learning something new, I don't yet have a firm grasp on idiomatic implementations, or simply put, how to do something the "right" way.

所以我是一个系统程序员,目前正在自学web应用程序编程。就像学习新东西时的情况一样,我还不能很好地理解习惯实现,或者简单地说,如何以“正确”的方式做某事。

After taking some time building a few games and trivial UI's using nothing but HTML and javascript, I am now venturing out into a non-trivial dynamic application. I am using Node as my server and have a question concerning how to route response handlers.

在花了一段时间构建了一些游戏和简单的UI(除了HTML和javascript之外什么都不用)之后,我现在冒险进入一个重要的动态应用程序。我使用Node作为我的服务器,并且有一个关于如何路由响应处理程序的问题。

I am following a (seemingly) nice guide found here. This is the only guide I have found so far that takes you through how to build an actual application (as opposed to something like response.write("Hello world"); response.end();).

我正在跟踪一个(看起来)很好的向导。这是我到目前为止所发现的唯一指导,可以帮助您了解如何构建一个实际的应用程序(而不是响应之类的东西)。写(“Hello world”);response.end();。

The author proposes adding response handlers like so:

作者建议增加响应处理程序如下:

var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");

var handle = {}
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;

server.start(router.route, handle);

The code should be self-explanatory, but essentially he is using an object as an associative container to map the resource requested in a query string to a handler. That's all well and good, but I would like to avoid adding a line to this file every time I add a new handler.

代码应该是自解释的,但本质上,他使用对象作为关联容器,将查询字符串中请求的资源映射到处理程序。这一切都很好,但是我希望每次添加一个新的处理程序时避免在这个文件中添加一行。

My idea was this; create a module for each handler and use some common interface to handle the response. Something like:

我的想法是;为每个处理程序创建一个模块,并使用一些通用接口来处理响应。喜欢的东西:

function handleReq(...) {
    ...
}

exports.handleRequest = handleReq;

I could then just require the module dynamically, i.e.,

我可以动态地要求这个模块,例如,

// in my router module
function route(pathName, args) {
    // where 'pathName' is something obtained
    // in a manner like so in the request handler:
    // url.parse(request.url).pathname;  

    var handler = require(pathName);
    handler.handleRequest(args);
}

Is there some flaw I am not seeing in this approach? It seems as though it would cut down on redundant code, but being a beginner in this field/technology I am suspicious. Perhaps the author just wanted to keep it simple, or as I guess may be the case, I am missing something.

我在这个方法中没有看到什么缺陷吗?它似乎可以减少冗余代码,但作为这个领域/技术的初学者,我对此持怀疑态度。也许作者只是想简单点,或者正如我猜想的那样,我漏掉了一些东西。

Cheers and thanks in advance. Don't feel free to throw other seemingly unrelated advice at me as well should you see a reason to do so.

提前欢呼和感谢。如果你有理由这样做的话,也不要随意向我提出其他看似无关的建议。

1 个解决方案

#1


4  

There are lots of ways of doing such things, I think the guide was trying to be simple.

做这样的事情有很多种方式,我认为指南尽量简单。

I tend to do stuff like this: Create modules that have handlers in them, and to add a new handler just add it to the module in the right place, and it will automatically work...no need to modify any other code. The server code just has to try calling moduleName.handleRequest(scriptName, req, resp); and if it returns true, it was successful. (it can try it on all the modules that have handlers, if none return true, it can show a 404)

我倾向于这样做:创建包含处理程序的模块,并添加一个新的处理程序,只要将它添加到适当的模块中,它就会自动工作……不需要修改任何其他代码。服务器代码只需尝试调用moduleName。handleRequest(scriptName、要求、职责);如果它是真的,那么它是成功的。(它可以在所有有处理程序的模块上尝试它,如果没有返回true,它可以显示404)

scriptName is assumed to have had the path trimmed off it (so "/start" would just be "start", etc), if you really need to use the path in determining which handler to dispatch it to, I'm sure you could build that in in an elegant way, but I didn't bother.

假定scriptName已经删除了路径(因此“/start”将仅仅是“start”,等等),如果您确实需要使用路径来确定发送给哪个处理程序,我相信您可以以一种优雅的方式构建它,但我没有麻烦。

Within the module itself, you can have something like this:

在模块内部,你可以有这样的东西:

var handlers = {
 start : function (req, resp) {
  // ...
  },

 upload : function (req, resp) {
  // ...
  } 
};

export.handleRequest(name, req, resp) {
  if (handlers[name] !== undefined) {
    handlers[name](req,resp);
    return true;
  }
  // do special cases (if there are any)
  if (name === '') {
    handlers.start(req,resp);
    return true;
  }
  return false; // not found
}

This is really just one step up in terms of complexity/sophistication from the example you cite. You can keep going till you have a full-fledged framework.

从您引用的示例来看,这实际上只是在复杂性/复杂性方面迈出的一步。你可以继续,直到你有一个完整的框架。

#1


4  

There are lots of ways of doing such things, I think the guide was trying to be simple.

做这样的事情有很多种方式,我认为指南尽量简单。

I tend to do stuff like this: Create modules that have handlers in them, and to add a new handler just add it to the module in the right place, and it will automatically work...no need to modify any other code. The server code just has to try calling moduleName.handleRequest(scriptName, req, resp); and if it returns true, it was successful. (it can try it on all the modules that have handlers, if none return true, it can show a 404)

我倾向于这样做:创建包含处理程序的模块,并添加一个新的处理程序,只要将它添加到适当的模块中,它就会自动工作……不需要修改任何其他代码。服务器代码只需尝试调用moduleName。handleRequest(scriptName、要求、职责);如果它是真的,那么它是成功的。(它可以在所有有处理程序的模块上尝试它,如果没有返回true,它可以显示404)

scriptName is assumed to have had the path trimmed off it (so "/start" would just be "start", etc), if you really need to use the path in determining which handler to dispatch it to, I'm sure you could build that in in an elegant way, but I didn't bother.

假定scriptName已经删除了路径(因此“/start”将仅仅是“start”,等等),如果您确实需要使用路径来确定发送给哪个处理程序,我相信您可以以一种优雅的方式构建它,但我没有麻烦。

Within the module itself, you can have something like this:

在模块内部,你可以有这样的东西:

var handlers = {
 start : function (req, resp) {
  // ...
  },

 upload : function (req, resp) {
  // ...
  } 
};

export.handleRequest(name, req, resp) {
  if (handlers[name] !== undefined) {
    handlers[name](req,resp);
    return true;
  }
  // do special cases (if there are any)
  if (name === '') {
    handlers.start(req,resp);
    return true;
  }
  return false; // not found
}

This is really just one step up in terms of complexity/sophistication from the example you cite. You can keep going till you have a full-fledged framework.

从您引用的示例来看,这实际上只是在复杂性/复杂性方面迈出的一步。你可以继续,直到你有一个完整的框架。