JavaScript
Article

Getting started with Connect

By Abbas Suterwala

If you need to write modular and reusable components, Connect could be the best solution for you. It deals with an extensible HTTP server framework for Node.js using “plugins” known as middleware.

A middleware component is a plugin that gets a request and then does some processing, after which it might handle and end the requests or pass them on the next middleware plugin. The plugins that process the request and pass it on the next handlers are called filters, while the ones that actually handle the request are known as providers. In the first group we can find request logging plugin or authentication plugin, just to mention a few examples. As for the providers, they would mainly be part of the business logic of your application.

In this article you’ll see how to get started and use the Connect middleware framework in your Node.js applications.

Setting up Connect

For Node.js the package dependency is done with npm, which lets you specify and get the dependent packages required for your application. The package dependencies for npm are defined in a file called package.json. Though this file can be written by hand, it would better and strongly recommended to use the npm command to create it.

To achieve this task, run the following command:

$ npm init

And then eply to the questions it’ll show (such as package name and so on). Once done, your “package.json” file should appear in the root folder with content that resembles the one below:

{
  "name": "nodejs-connect-demo",
  "version": "1.0.0",
  "description": "Demo on how to use connect framework for Node.js",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/abbassoftware/nodejs-connect-demo.git"
  },
  "keywords": [
    "connect"
  ],
  "author": "Abbas",
  "license": "",
  "bugs": {
    "url": "https://github.com/abbassoftware/nodejs-connect-demo/issues"
  },
  "homepage": "https://github.com/abbassoftware/nodejs-connect-demo"
}

This file already contains information about the project, but it has no dependencies declared. To declare Connect as dependency, you need to add the dependency value in your “package.json” file and update it as follows:

{
  ...
  "dependencies": {
        "connect": "3.x"
  },
  ...
}

Alternatively, you could run the command:

npm install connect --save

At this point, we can run the following npm command to download all the dependencies (only Connect in this case):

$ npm install

Creating a “Hello World” Component to Respond to Requests

Once the dependencies have been specified, we can move on creating a middleware provider which responds to all the requests using the Hello Connect response. To do that, create a “server.js” file in your Node.js project directory and add the following code:

var connect = require("connect");
var app = connect();

function sayHello(req, res, next) {
    res.setHeader('Content-Type', 'text/plain');
    res.end('Hello Connect');
}

app
   .use(sayHello)
   .listen(3031);

console.log("Server is listening");

In the above code, we first load the Connect module using Node.js require() function, and then create a server using the return value of the function. Secondly, we create a middleware component, that is nothing but a function, which takes three parameters: request, response, and next. next represents the next handler in the chain. The sayHello() function sets the header and the response text in the response object. Afterward we use this middleware component thanks to the use() function. Finally, we allow the server to listen on port 3031.

Now, we can run our Connect app using the command below:

node server

If we point our browser to localhost:3031, we should be able to see the output as follows:

Hello Connect

The Request and Response objects

In this section, we’ll delve into the request, response, and next parameters we mentioned in the previous section. The request object holds the details about the incoming request. Some of the most important information in the request objects are:

  • method: contains the type of the request: GET, POST, and so on.
  • url: contains the complete URL of the request. You can parse this URL to get the query parameters for GET requests.
  • headers: it’s the property that you can use to the request headers.

The response object holds the response that will be sent back. You can add headers and data to it depending on your application. Some important functions of the response object are:

  • setHeader() : This method adds a header to the response.
  • removeHeader(): This method removes a header to the response.
  • write(): It’s useful to write a partial response to the response object.
  • end(): It’s a method used to mark the end of the response.

Using Multiple Middleware Components in Connect

In the last section we have created a middleware provider which responds with ‘Hello connect’ to all the requests. Now we’ll add one more filter middleware which logs the details of the incoming request. Then, we’ll pass the request to our sayHello() that will return the response. To achieve this other task, we’ll update our “server.js” file with the following code:

var connect = require("connect");
var url = require('url');
var app = connect();

function sayHello(req, res, next) {
    res.setHeader('Content-Type', 'text/plain');
    res.write('Write first chunk. ');
    res.write('Write second chunk. ');
    res.end('Hello Connect');
}

function loggingMiddleware(req, res, next) {
    console.log("The request method is: " + req.method );
    console.log("The request url is: " + req.url );
    var queryData = url.parse(req.url, true).query;
    console.log("The query parameters are : " + queryData.name );
    next();
}

app
   .use(loggingMiddleware)
   .use(sayHello)
   .listen(3031);

console.log("Server is listening");

In the above code we have added one more middleware component using the loggingMiddleware() function. It logs the URL and the method of the request, and parses the URL to print a possible name parameter provided. Then, it calls the next() function which will pass the request to the next handler.

When we make the Connect server listen to the port, firstly we use loggingMiddleware() and then sayHello(). Now, if we start the Node.js server and run the following command:

curl http://localhost:3031?name=abbas

we’ll see the following messages:

middleware components

Adding an Authentication Handler

The next thing to do is to add an authentication to the admin section of our website using the Basic access authentication of HTTP. To do that, we have to explore how can we run a handler just for the admin section of our server. Connect’s use() function can take the first parameter as what should be the path in request.url for the handler to get invoked. So, if we want the authentication handler exclusively for the admin section, we need to update the “server.js” file as follows:

var connect = require("connect");
var url = require('url');
var app = connect();
var authJsonObj = require("./authDetails.json");

function sayHello(req, res, next) {
    res.setHeader('Content-Type', 'text/plain');
    res.write('Write first chunk. ');
    res.write('Write second chunk. ');
    res.end('Hello Connect');
}

function loggingMiddleware(req, res, next) {
    console.log("The request method is : " + req.method );
    console.log("The request url is : " + req.url );
    var queryData = url.parse(req.url, true).query;
    console.log("The query parameters are : " + queryData.name );
    next();
}

function authenticateAdmin(req, res, next) {
    console.log("authenticateAdmin");
    var authorization = req.headers.authorization;
    //if the Authorization header is not present return error.
    if (!authorization) return returnAuthError(res);

    var parts = authorization.split(' ');

    //Check the Authorisation header contains both the parts.
    if (parts.length !== 2) return returnAuthError(res);

    //Check the Authorization header Scheme is correct.
    var scheme = parts[0];
    if ('Basic' != scheme) return returnAuthError(res);

    //Credentials will be base64 encoded. After decoding they will be in the format username:password
    var credentials = new Buffer(parts[1], 'base64').toString()
    var index = credentials.indexOf(':');

    var user = credentials.slice(0, index)
    var pass = credentials.slice(index + 1);

    //If the password does not match return error.
    if(authJsonObj[user] != pass) return returnAuthError(res);

    //Auth is complete pass to the next handler.
    next();
}

function returnAuthError(res) {
  res.statusCode = 401;
  res.end('Unauthorized');
};

app
   .use(loggingMiddleware)
   .use('/admin', authenticateAdmin)
   .use(sayHello)
   .listen(3031);

console.log("Server is listening");

Then we need to create a “authDetails.json” file in the same directory of “server.js” with the following content:

{
   "abbas":"pass123",
   "admin":"pass456"
}

In the above code we load a JSON file called “authDetails.json” (the one just created) which will include a JSON object containing the username and password lists of the authorized users. Then we add one more Connect handler called authenticateAdmin used only for the admin section of the website. The previously mentioned handler checks the authorization header and then decodes the username/password pair, and checks it against the JSON file contents for authorization. In case the request is not authorized, an unauthorized response with response code 401 is sent to the client.

With this update, if we make requests to the admin section of the site, the output will be the following:

request to admin section

Conclusions

In this article we have deepened the features of a small and powerful Node.js’ module called Connect. It can help you building middleware components to easily handle requests. Using Connect and middleware plugins will reduce your efforts and transform your application in a more structured and usable project.

What about you? Have you ever tried it? Let’s start a discussion.

No Reader comments

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in JavaScript, once a week, for free.