Node.js routing


We need to provide the requested URL and other required GET and POST parameters for the routing, and then the routing needs to execute the corresponding code based on these data.

Therefore, we need to look at the HTTP request and extract the requested URL and GET/POST parameters. Whether this function belongs to routing or server (or even as a function of the module itself) is indeed worthy of discussion, but here it is tentatively considered as the function of our HTTP server.

All the data we need will be contained in the request object, which is passed as the first parameter of the onRequest() callback function. But in order to parse this data, we need additional Node.JS modules, which are the url and querystring modules.

                   url.parse(string).query
                                           |
           url.parse(string).pathname      |
                       |                   |
                       |                   |
                     ------ -------------------
http://localhost:8888/start?foo=bar&hello=world
                                ---       -----
                                 |          |
                                 |          |
              querystring(string)["foo"]    |
                                            |
                         querystring(string)["hello"]

Of course we can also use the querystring module to parse the parameters in the POST request body, which will be demonstrated later.

Now let’s add some logic to the onRequest() function to find out the URL path requested by the browser:

var http = require("http");
var url = require("url");

function start() {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

Okay, our application can now pass the requested URL path to differentiate between different requests - this allows us to use routing (not yet complete) to map requests to handlers based on URL paths.

In the application we are building, this means that requests from /start and /upload can be handled with different code. We'll see how this fits together later.

Now we can write the route. Create a file named router.js and add the following content:

function route(pathname) {
  console.log("About to route a request for " + pathname);
}

exports.route = route;

As you can see, what is this code? I didn’t do it either, but for now this is what it should be. Before adding more logic, let's first look at how to integrate routing and servers.

Our server should be aware of the existence of routes and use them effectively. We could of course hard-code this dependency to the server, but experience with programming in other languages ​​tells us that this would be a pain, so we will use dependency injection to loosely add the route. module.

First, let’s expand the server’s start() function to pass the routing function as a parameter. server.js The file code is as follows

var http = require("http");
var url = require("url");

function start(route) {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");

    route(pathname);

    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

At the same time, we Index.js will be extended accordingly so that the routing function can be injected into the server:

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

server.start(router.route);

Here, the function we pass still does nothing.

If you start the application now (node ​​index.js, always remember this command line) and then request a URL, you will see the application output the corresponding information, which indicates that our HTTP server is already using the routing module , and will pass the requested path to the routing:

$ node index.js
Server has started.

The above output has removed the more annoying /favicon.ico request-related parts.

Browser access http://127.0.0.1:8888/, the output result is as follows:

251.jpg