Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Node.js Blueprints
Node.js Blueprints

Node.js Blueprints: Develop stunning web and desktop applications with the definitive Node.js

Arrow left icon
Profile Icon Krasimir Stefanov Tsonev
Arrow right icon
$24.99 $36.99
Full star icon Full star icon Full star icon Full star icon Half star icon 4.7 (10 Ratings)
eBook Jun 2014 268 pages 1st Edition
eBook
$24.99 $36.99
Paperback
$60.99
Subscription
Free Trial
Renews at $19.99p/m
Arrow left icon
Profile Icon Krasimir Stefanov Tsonev
Arrow right icon
$24.99 $36.99
Full star icon Full star icon Full star icon Full star icon Half star icon 4.7 (10 Ratings)
eBook Jun 2014 268 pages 1st Edition
eBook
$24.99 $36.99
Paperback
$60.99
Subscription
Free Trial
Renews at $19.99p/m
eBook
$24.99 $36.99
Paperback
$60.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

Node.js Blueprints

Chapter 1. Common Programming Paradigms

Node.js is a JavaScript-driven technology. The language has been in development for more than 15 years, and it was first used in Netscape. Over the years, they've found interesting and useful design patterns, which will be of use to us in this book. All this knowledge is now available to Node.js coders. Of course, there are some differences because we are running the code in different environments, but we are still able to apply all these good practices, techniques, and paradigms. I always say that it is important to have a good basis to your applications. No matter how big your application is, it should rely on flexible and well-tested code. The chapter contains proven solutions that guarantee you a good starting point. Knowing design patterns doesn't make you a better developer because in some cases, applying the principles strictly won't work. What you actually get is ideas, which will help you in thinking out of the box. Sometimes, programming is all about managing complexity. We all meet problems, and the key to a well-written application is to find the best suitable solutions. The more paradigms we know, the easier our work is because we have proven concepts that are ready to be applied. That's why this book starts with an introduction to the most common programming paradigms.

Node.js fundamentals

Node.js is a single-threaded technology. This means that every request is processed in only one thread. In other languages, for example, Java, the web server instantiates a new thread for every request. However, Node.js is meant to use asynchronous processing, and there is a theory that doing this in a single thread could bring good performance. The problem of the single-threaded applications is the blocking I/O operations; for example, when we need to read a file from the hard disk to respond to the client. Once a new request lands on our server, we open the file and start reading from it. The problem occurs when another request is generated, and the application is still processing the first one. Let's elucidate the issue with the following example:

var http = require('http');
var getTime = function() {
  var d = new Date();
  return  d.getHours() + ':' + d.getMinutes() + ':' + 
      d.getSeconds() + ':' + d.getMilliseconds();
}
var respond = function(res, str) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end(str + '\n');
  console.log(str + ' ' + getTime());
}
var handleRequest = function (req, res) {
  console.log('new request: ' + req.url + ' - ' + getTime());
  if(req.url == '/immediately') {
    respond(res, 'A');
  } else {
    var now = new Date().getTime();
    while(new Date().getTime() < now + 5000) {
      // synchronous reading of the file
    }
    respond(res, 'B');
  }
}
http.createServer(handleRequest).listen(9000, '127.0.0.1');

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

The http module, which we initialize on the first line, is needed for running the web server. The getTime function returns the current time as a string, and the respond function sends a simple text to the browser of the client and reports that the incoming request is processed. The most interesting function is handleRequest, which is the entry point of our logic. To simulate the reading of a large file, we will create a while cycle for 5 seconds. Once we run the server, we will be able to make an HTTP request to http://localhost:9000. In order to demonstrate the single-thread behavior we will send two requests at the same time. These requests are as follows:

  • One request will be sent to http://localhost:9000, where the server will perform a synchronous operation that takes 5 seconds
  • The other request will be sent to http://localhost:9000/immediately, where the server should respond immediately

The following screenshot is the output printed from the server, after pinging both the URLs:

Node.js fundamentals

As we can see, the first request came at 16:58:30:434, and its response was sent at 16:58:35:440, that is, 5 seconds later. However, the problem is that the second request is registered when the first one finishes. That's because the thread belonging to Node.js was busy processing the while loop.

Of course, Node.js has a solution for the blocking I/O operations. They are transformed to asynchronous functions that accept callback. Once the operation finishes, Node.js fires the callback, notifying that the job is done. A huge benefit of this approach is that while it waits to get the result of the I/O, the server can process another request. The entity that handles the external events and converts them into callback invocations is called the event loop. The event loop acts as a really good manager and delegates tasks to various workers. It never blocks and just waits for something to happen; for example, a notification that the file is written successfully.

Now, instead of reading a file synchronously, we will transform our brief example to use asynchronous code. The modified example looks like the following code:

var handleRequest = function (req, res) {
  console.log('new request: ' + req.url + ' - ' + getTime());
  if(req.url == '/immediately') {
    respond(res, 'A');
  } else {
    setTimeout(function() {
      // reading the file
      respond(res, 'B');	
      }, 5000);	  	
    }
}

The while loop is replaced with the setTimeout invocation. The result of this change is clearly visible in the server's output, which can be seen in the following screenshot:

Node.js fundamentals

The first request still gets its response after 5 seconds. However, the second one is processed immediately.

Organizing your code logic in modules

If we write a lot of code, sooner or later, we will start realizing that our logic should be split into different modules. In most languages, this is done through classes, packages, or some other language-specific syntax. However, in JavaScript, we don't have classes natively. Everything is an object, and in practice, objects inherit other objects. There are several ways to achieve object-oriented programming within JavaScript. You can use prototype inheritance, object literals, or play with function calls. Thankfully, Node.js has a standardized way of defining modules. This is approached by implementing CommonJS, which is a project that specifies an ecosystem for JavaScript.

So, you have some logic, and you want to encapsulate it by providing useful API methods. If you reach that moment, you are definitely in the right direction. This is really important, and maybe it is one of the most challenging aspects of programming nowadays. The ability to split our applications into different parts and delegate functions to them is not always an easy task. Very often, this is undervalued, but it's the key to good architecture. If a module contains a lot of dependencies, operates with different data storages, or has several responsibilities, then we are doing something wrong. Such code cannot be tested and is difficult to maintain. Even if we take care about these two things, it is still difficult to extend the code and continue working with it. That's why it's good to define different modules for different functionalities. In the context of Node.js, this is done via the exports keyword, which is a reference to module.exports.

Building a car construction application

Let's elucidate the process with a simple example. Assume that we are building an application that constructs a car. We need one main module (car) and a few other modules, which are responsible for the different parts of the car (wheels, windows, doors, and so on). Let's start with the definition of a module representing the wheels of the car, with the following code:

// wheels.js
var typeOfTires;
exports.init = function(type) {
    typeOfTires = type;
}
exports.info = function() {
  console.log("The car uses " + typeOfTires + " tires.");
}

The preceding code could be the content of wheels.js. It contains two methods. The first method, init, should be called first and accepts one setting, that is, the type of the wheels' tires. The second method simply outputs some information. In our main file, car.js, we have to get an instance of the wheels and use the provided API methods. This can be done as follows:

// cars.js
  var wheels = require("./wheels.js");
  wheels.init("winter");
  wheels.info();

When you run the application with node car.js, you will get the following output:

The car uses winter tires.

So, everything that you want to expose to the outside world should be attached to the export object. Note that typeOfTires is a local variable for the module. It is available only in wheels.js and not in car.js. It's also a common practice to apply an object or a function to the exports object directly, as shown in the following code for example:

// engine.js
var Class = function() {
    // ...
}
Class.prototype = {
  forward: function() {
    console.log("The car is moving forward.");
  },
  backward: function() {
    console.log("The car is moving backward.");	
  } 
}
module.exports = Class;

In JavaScript, everything is an object and that object has a prototype property. It's like a storage that keeps the available variables and methods. The prototype property is heavily used during inheritance in JavaScript, because it provides a mechanism for transferring logic.

We will also clear the difference between module.exports and exports. As you can see, in wheels.js, we assigned two functions, init and info, directly to the exports global object. In fact, that object is a reference to module.exports, and every function or variable attached to it is available to the outside world. However, if we assign a new object or function directly to the export object, we should not expect to get an access to it after requiring the file. This should be done with module.exports. Let's take the following code as an example:

// file.js
module.exports.a = 10;
exports.b = 20;

// app.js
var file = require('./file');
console.log(file.a, file.b);

Let's say that both the files, app.js and file.js, are in the same directory. If we run node app.js, we will get 10 20 as the result. However, consider what would happen if we changed the code of file.js to the following code:

module.exports = { a: 10 };
exports.b = 20;

Then, in this case, we would get 10 undefined as the result. That's because module.exports has a new object assigned and exports still points to the old one.

Using the car's engine

Let's say that the module in engine.js controls the car. It has methods for moving the car forward and backward. It is a little different because the logic is defined in a separate class and that class is directly passed as a value of module.exports. In addition, as we are exporting a function, and not just an object, our instance should be created with the new keyword. We will see how the car's engine works with the new keyword as shown in the following code:

var Engine = require("./engine.js");
var e = new Engine();
e.forward();

There is a significant difference between using JavaScript functions as constructors and calling them directly. When we call the function as a constructor, we get a new object with its own prototype. If we miss the new keyword, the value which we get at the end is the result of the function's invocation.

Node.js caches the modules returned by the require method. It's done to prevent the blocking of the event loop and increase the performance. It's a synchronous operation, and if there is no cache, Node.js will have to do the same job repeatedly. It's also good to know that we can call the method with just a folder name, but there should be a package.json or an index.js file inside the directory. All these mechanisms are described well in the official documentation of Node.js at http://nodejs.org/. What is important to note here is that the environment encourages modular programming. All we need is native implementation into the system, and we don't have to use a third-party solution that provides modularity.

Like in the client-side code, every Node.js module can be extended. Again, as we are writing the code in plain JavaScript, we can use the well-known approaches for inheritance. For example, take a look at the following code:

var Class = function() { }
Class.prototype = new require('./engine.js')();
Class.prototype.constructor = Class;

Node.js even offers a helper method for this purpose. Let's say that we want to extend our engine.js class and add API methods to move the car in the left and right directions. We can do this with the following piece of code:

// control.js
var util = require("util");
var Engine = require("./engine.js");
var Class = function() { }
util.inherits(Class, Engine); 
Class.prototype.left = function() {
  console.log("The car is moving to left.");
};
Class.prototype.right = function() {
  console.log("The car is moving to right.");  
}
module.exports = Class;

The first line gets a reference to the Node.js native utils module. It's full of useful functions. The fourth line is where the magic happens. By calling the inherits method, we have actually set a new prototype of our Class object. Keep in mind that every new method should use the already applied prototype. That's why the left and right methods are defined after the inheritance. At the end, our car will move in four directions, as shown in the following code snippet:

var Control = require("./control.js");
var c = new Control();
c.forward();
c.right();

Understanding inter-module communication

We've found out how to put our code logic into modules. Now, we need to know how to make them communicate with each other. Very often, people describe Node.js as an event-driven system. It's also called non-blocking because as we have seen earlier in the chapter, it can accept a new request even before the previous request is fully complete. That's very efficient and highly scalable. The events are very powerful and are good means to inform the other modules of what is going on. They bring about encapsulation, which is very important in modular programming. Let's add some events to the car example we discussed earlier. Let's say that we have air conditioning, and we need to know when it is started. The implementation of such logic consists of two parts. The first one is the air conditioning module. It should dispatch an event that indicates the start of the action. The second part is the other code that listens for that event. We will create a new file called air.js containing the logic responsible for the air conditioning, as follows:

// air.js
var util = require("util");
var EventEmitter = require('events').EventEmitter;
var Class = function() { }
util.inherits(Class, EventEmitter);
Class.prototype.start = function() {
  this.emit("started");
};
module.exports = Class;

Our class extends a Node.js module called EventEmitter. It contains methods such as emit or on, which help us to establish event-based communication. There is only one custom method defined: start. It simply dispatches an event that indicates that the air conditioning is turned on. The following code shows how we can attach a listener:

// car.js
var AirConditioning = require("./air.js");
var air = new AirConditioning();
air.on("started", function() {
  console.log("Air conditioning started");
});
air.start();

A new instance of the AirConditioning class is created. We attached an event listener and fired the start method. The handler is called, and the message is printed to the console. The example is a simple one but shows how two modules communicate. It's a really powerful approach because it offers encapsulation. The module knows its responsibilities and is not interested in the operations in the other parts of the system. It simply does its job and dispatches notifications (events). For example, in the previous code, the AirConditioning class doesn't know that we will output a message when it is started. It only knows that one particular event should be dispatched.

Very often, we need to send data during the emitting of an event. This is really easy. We just have to pass another parameter along with the name of the event. Here is how we send a status property:

Class.prototype.start = function() {
  this.emit("started", { status: "cold" });
};

The object attached to the event contains some information about the air conditioning module. The same object will be available in the listener of the event. The following code shows us how to get the value of the status variable mentioned previously:

air.on("started", function(data) {
  console.log("Status: " + data.status);
});

There is a design pattern that illustrates the preceding process. It's called the Observer. In the context of that pattern, our air conditioning module is called subject, and the car module is called the observer. The subject broadcasts messages or events to its observers, notifying them that something has changed.

If we need to remove a listener, Node.js has a method for that called removeListener. We can even allow a specific number of observers using setMaxListeners. Overall, the events are one of the best ways to wire your logical parts. The main benefit is that you isolate the module, but it is still highly communicative with the rest of your application.

Asynchronous programming

As we already learned, in nonblocking environments, such as Node.js, most of the processes are asynchronous. A request comes to our code, and our server starts processing it but at the same time continues to accept new requests. For example, the following is a simple file reading:

fs.readFile('page.html', function (err, content) {
  if (err) throw err;
  console.log(content);
});

The readFile method accepts two parameters. The first one is a path to the file we want to read, and the second one is a function that will be called when the operation finishes. The callback is fired even if the reading fails. Additionally, as everything can be done via that asynchronous matter, we may end up with a very long callback chain. There is a term for that—callback hell. To elucidate the problem, we will extend the previous example and do some operations with the file's content. In the following code, we are nesting several asynchronous operations:

fs.readFile('page.html', function (err, content) {
  if(err) throw err;
  getData(function(data) {
    applyDataToTheTemplate(content, data, function(resultedHTML) {
      renderPage(resultedHTML, function() {
        showPage(function() {
          // finally, we are done
        });
     });
  });
  });
});

As you can see, our code looks bad. It's difficult to read and follow. There are a dozen instruments that can help us to avoid such situations. However, we can fix the problem ourselves. The very first step to do is to spot the issue. If we have more than four or five nested callbacks, then we definitely should refactor our code. There is something very simple, which normally helps, that makes the code shallow. The previous code could be translated to a more friendly and readable format. For example, see the following code:

var onFileRead = function(content) {
  getData(function(data) {
    applyDataToTheTemplate(content, data, dataApplied);
  });
}
var dataApplied = function(resultedHTML) {
  renderPage(resultedHTML, function() {
    showPage(weAreDone);
  });
}
var weAreDone = function() {
  // finally, we are done
}
fs.readFile('page.html', function (err, content) {
  if (err) throw err;
    onFileRead(content);
});

Most of the callbacks are just defined separately. It is clear what is going on because the functions have descriptive names. However, in more complex situations, this technique may not work because you will need to define a lot of methods. If that's the case, then it is good to combine the functions in an external module. The previous example can be transformed to a module that accepts the name of a file and the callback function. The module is as follows:

var renderTemplate = require("./renderTemplate.js");
renderTemplate('page.html', function() {
  // we are done
});

You still have a callback, but it looks like the helper methods are hidden and only the main functionality is visible.

Another popular instrument for dealing with asynchronous code is the promises paradigm. We already talked about events in JavaScript, and the promises are something similar to them. We are still waiting for something to happen and pass a callback. We can say that the promises represent a value that is not available at the moment but will be available in the future. The syntax of promises makes the asynchronous code look synchronous. Let's see an example where we have a simple module that loads a Twitter feed. The example is as follows:

var TwitterFeed = require('TwitterFeed');
TwitterFeed.on('loaded', function(err, data) {
  if(err) {
      // ...
   } else {
      // ...
   }
});
TwitterFeed.getData();

We attached a listener for the loaded event and called the getData method, which connects to Twitter and fetches the information. The following code is what the same example will look like if the TwitterFeed class supports promises:

var TwitterFeed = require('TwitterFeed');
var promise = TwitterFeed.getData();
promise.then(function(data) {
  // ...
}, function(err) {
  // ...
});

The promise object represents our data. The first function, which is sent to the then method, is called when the promise object succeeds. Note that the callbacks are registered after calling the getData method. This means that we are not rigid to actual process of getting the data. We are not interested in when the action occurs. We only care when it finishes and what its result is. We can spot a few differences from the event-based implementation. They are as follows:

  • There is a separate function for error handling.
  • The getData method can be called before calling the then method. However, the same thing is not possible with events. We need to attach the listeners before running the logic. Otherwise, if our task is synchronous, the event may be dispatched before our listener attachment.
  • The promise method can only succeed or fail once, while one specific event may be fired multiple times and its handlers can be called multiple times.

The promises get really handy when we chain them. To elucidate this, we will use the same example and save the tweets to a database with the following code:

var TwitterFeed = require('TwitterFeed');
var Database = require('Database');
var promise = TwitterFeed.getData();
promise.then(function(data) {
  var promise = Database.save(data);
  return promise;
}).then(function() {
  // the data is saved
  // into the database
}).catch(function(err) {
  // ...
});

So, if our successful callback returns a new promise, we can use then for the second time. Also, we have the possibility to set only one error handler. The catch method at the end is fired if some of the promises are rejected.

There are four states of every promise, and we should mention them here because it's a terminology that is widely used. A promise could be in any of the following states:

  • Fulfilled: A promise is in the fulfilled state when the action related to the promise succeeds
  • Rejected: A promise is in the rejected state when the action related to the promise fails
  • Pending: A promise is in the pending state if it hasn't been fulfilled or rejected yet
  • Settled: A promise is in a settled state when it has been fulfilled or rejected

The asynchronous nature of JavaScript makes our coding really interesting. However, it could sometimes lead to a lot of problems. Here is a wrap up of the discussed ideas to deal with the issues:

  • Try to use more functions instead of closures
  • Avoid the pyramid-looking code by removing the closures and defining top-level functions
  • Use events
  • Use promises

Exploring middleware architecture

The Node.js framework is based on the middleware architecture. That's because this architecture brings modularity. It's really easy to add or remove functionalities from the system without breaking the application because the different modules do not depend on each other. Imagine that we have several modules that are all stored in an array, and our application starts using them one by one. We are controlling the whole process, that is, the execution continues only if we want it to. The concept is demonstrated in the following diagram:

Exploring middleware architecture

Connect (https://github.com/senchalabs/connect) is one of the first frameworks that implements this pattern. In the context of Node.js, the middleware is a function that accepts the request, response, and the next callbacks. The first two parameters represent the input and output of the middleware. The last one is a way to pass the flow to the next middleware in the list. The following is a short example of this:

var connect = require('connect'),
    http = require('http');
 
var app = connect()
  .use(function(req, res, next) {
    console.log("That's my first middleware");
    next();
  })
  .use(function(req, res, next) {
    console.log("That's my second middleware");
    next();
  })
  .use(function(req, res, next) {
    console.log("end");
    res.end("hello world");
  });
 
http.createServer(app).listen(3000);

The use method of connect accepts middleware. In general, the middleware is just a simple JavaScript function. We can write whatever we want in it. What is important to do at the end is to call the next method. It passes the flow to the next middleware. Often, we will need to transfer data between the middleware. It's a common practice to modify the request or the response objects because they are the input and output of the module. We can attach new properties or functions, and they will be available for the next middleware in the list. As in the following code snippet, we are attaching an object to a data property.

.use(function(req, res, next) {
    req.data = { value: "middleware"};
    next();
})
.use(function(req, res, next) {
    console.log(req.data.value);
})

The request and response objects are identical in every function. Thus, the middleware share the same scope. At the same time, they are completely independent. This pattern provides a really flexible development environment. We can combine modules that do different tasks written by different developers.

Composition versus inheritance

In the previous section, we learned how to create modules, how to make them communicate, and how to use them. Let's talk a bit about how to architect modules. There are dozens of ways to build a good application. There are also some great books written only on this subject, but we will focus on two of the most commonly used techniques: composition and inheritance. It's really important to understand the difference between the two. They both have pros and cons. In most of the cases, their usage depends on the current project.

The car class from the previous sections is a perfect example of composition. The functionalities of the car object are built by other small objects. So, the main module actually delegates its jobs to other classes. For example, the wheels or the air conditioning of the car are controlled by externally defined modules:

var wheels = require("./wheels.js")();
var control = require("./control.js")();
var airConditioning = require("./air.js")();
module.export = {
  run: function() {
    wheels.init();
    control.forward();
    airConditioning.start();
  }
}

For the outside world, the car has only one method: run. However, what happens is that we perform three different operations, and they are defined in other modules. Often, the composition is preferred over the inheritance because while using this approach, we can easily add as many modules as we want. It's also interesting that we cannot only include modules but also other compositions.

On the other side is the inheritance. The following code is a typical example of inheritance:

var util = require("util");
var EventEmitter = require('events').EventEmitter;
var Class = function() { }
util.inherits(Class, EventEmitter);

This code implies that our class needs to be an event emitter, so it simply inherits that functionality from another class. Of course, in this case, we can still use composition and create an instance of the EventEmitter class, define methods such as on and dispatch, and delegate the real work. However, here it is much better to use inheritance.

The truth is somewhere in between—the composition and the inheritance should play together. They are really great tools, but each of them has its own place. It's not only black and white, and sometimes it is difficult to find the right direction. There are three ways to add behavior to our objects. They are as follows:

  • Writing the functionality into the objects directly
  • Inheriting the functionality from a class that already has the desired behavior
  • Creating a local instance of an object that does the job

The second one is related to inheritance and the last one is actually a composition. By using composition, we are adding a few more abstraction layers, which is not a bad thing, but it could lead to unnecessary complexity.

Managing dependencies

Dependency management is one of the biggest problems in complex software. Often, we build our applications around third-party libraries or custom-made modules written for other projects. We do this because we don't want to reinvent the wheel every time.

In the previous sections of this chapter, we used the require global function. That's how Node.js adds dependencies to the current module. A functionality written in one JavaScript file is included in another file. The good thing is that the logic in the imported file lives in its own scope, and only the publicly exported functions and variables are visible to the host. With this behavior, we are able to separate our logic modules into Node.js packages. There is an instrument that controls such packages. It's called Node Package Manager (npm) and is available as a command-line instrument. Node.js has become so popular mainly because of the existence of its package manager. Every developer can publish their own package and share it with the community. The good versioning helps us to bind our applications to specific versions of the dependencies, which means that we can use a module that depends on other modules. The main rule to make this work is to add a package.json file to our project. We will add this file with the following code:

{
  "name": "my-awesome-module",
  "version": "0.1.10",
  "dependencies": {
    "optimist": "0.6.1",
    "colors": "0.6.2"
  }
}

The content of the file should be valid JSON and should contain at least the name and version fields. The name property should also be unique, and there should not be any other module with the same name. The dependencies property contains all the modules and versions that we depend on. To the same file, we can add a lot of other properties. For example, information about the author, a description of the package, the license of the project, or even keywords. Once the module is registered in the registry, we can use it as a dependency. We just need to add it in our package.json file, and after we run npm install, we will be able to use it as a dependency. Since Node.js adopts the module pattern, we don't need instruments such as the dependency injection container or service locater.

Let's write a package.json file for the car example used in the previous sections, as follows:

{
  "name": "my-awesome-car",
  "version": "0.0.1",
  "dependencies": {
    "wheels": "2.0.1",
    "control": "0.1.2",
    "air": "0.2.4"
  }
}

Summary

In this chapter, we went through the most common programming paradigms in Node.js. We learned how Node.js handles parallel requests. We understood how to write modules and make them communicative. We saw the problems of the asynchronous code and their most popular solutions. At the end of the chapter, we talked about how to construct our application. With all this as a basis, we can start thinking about better programs. Software writing is not an easy task and requires strong knowledge and experience. The experience usually comes after years of coding; however, knowledge is something that we can get instantly. Node.js is a young technology; nonetheless, we are able to apply paradigms and concepts from client-side JavaScript and even other languages.

In the next chapter, we will see how to use one of the most popular frameworks for Node.js, that is, Express.js, and we will build a simple website.

Left arrow icon Right arrow icon

Description

A straightforward, practical guide containing step-by-step tutorials that will push your Node.js programming skills to the next level. If you are a web developer with experience in writing client-side JavaScript and want to discover the fascinating world of Node.js to develop fast and efficient web and desktop applications, then this book is for you.

What you will learn

  • Explore design patterns in Node.js
  • Build solid architectures by following testdriven development
  • Look beyond web applications and create your own desktop app with Node.js
  • Develop single page applications using Node.js with AngularJS, Ember.js, and Backbone.js
  • Master the Express framework and build a complete site with a real database
  • Create a realtime and fully functional online chat application with Socket.IO
  • Utilize the enormous range of Grunt and Gulp plugins

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Jun 16, 2014
Length: 268 pages
Edition : 1st
Language : English
ISBN-13 : 9781783287345
Languages :
Tools :

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want

Product Details

Publication date : Jun 16, 2014
Length: 268 pages
Edition : 1st
Language : English
ISBN-13 : 9781783287345
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 170.97
Node Cookbook: Second Edition
$54.99
Node.js Blueprints
$60.99
Mastering Node.js
$54.99
Total $ 170.97 Stars icon

Table of Contents

13 Chapters
1. Common Programming Paradigms Chevron down icon Chevron up icon
2. Developing a Basic Site with Node.js and Express Chevron down icon Chevron up icon
3. Writing a Blog Application with Node.js and AngularJS Chevron down icon Chevron up icon
4. Developing a Chat with Socket.IO Chevron down icon Chevron up icon
5. Creating a To-do Application with Backbone.js Chevron down icon Chevron up icon
6. Using Node.js as a Command-line Tool Chevron down icon Chevron up icon
7. Showing a Social Feed with Ember.js Chevron down icon Chevron up icon
8. Developing Web App Workflow with Grunt and Gulp Chevron down icon Chevron up icon
9. Automate Your Testing with Node.js Chevron down icon Chevron up icon
10. Writing Flexible and Modular CSS Chevron down icon Chevron up icon
11. Writing a REST API Chevron down icon Chevron up icon
12. Developing Desktop Apps with Node.js Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Most Recent
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.7
(10 Ratings)
5 star 70%
4 star 30%
3 star 0%
2 star 0%
1 star 0%
Filter icon Filter
Most Recent

Filter reviews by




Duc T. Jun 07, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Great examples of tools and techniques I gathered by reading this book.
Amazon Verified review Amazon
Oguntunde Toyin Oct 14, 2015
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
I love the way Node.js Blueprints approached the concepts of Nodejs, ExpressJs and others modules for building apps. It's concise, step-by-step for a beginner and easy to comprehend. It's a great book for Node.js technology.
Amazon Verified review Amazon
W Boudville Aug 31, 2014
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
Node.js tackles well a persistent problem in code development. People often link to packages developed by others outside their firm. Simply because it is faster than re-inventing the wheel. Of necessity, you have to add value by making new things. But the downside is a rat's nest of package dependencies. The book starts by explaining how you can explicitly record the dependencies using Node Package Manager. An example is given in JSON format, which is intuitively readable. That is the point about JSON. Perhaps more than any other single feature of Node.js, this handling of dependencies could save you immense time in debugging and maintaining your code base.Granted, a novice programmer might not appreciate this. Not having endured in the trenches with a large code base or with having to maintain it. But experienced developers understand the significance.The text goes on to show how Node can be combined with another popular package, Angular.js. Where the example also demonstrates the use of a backend MySQL database. Important because many applications are more than just a user interface. Persistence to a database is typically needed.Another expansion in functionality is the use of WebSockets. Turns on a 2 way interaction between a browser and the web server. This can greatly expand the user's appreciation of what a browser can do. While Backbone.js is explained in its own chapter, for improved handling of jQuery. All of these are useful packages that you are likely to need.
Amazon Verified review Amazon
Rakesh Aug 08, 2014
Full star icon Full star icon Full star icon Full star icon Full star icon 5
There are hardly any good books on node.js available in market, but this is an exception. I went through blogs and posts just to find a good node.js book.Since i am pretty excited about learning node.js, i did not want my experience to be soured by "not so good" book. I had almost given up my search until i found this one. Reading it is a breeze and you do not want to put it down. Examples are mentioned very neatly and they are easy to understand. Just go through car example in first few pages and you will understand about modules, events, promises etc. My request to author would be to write more such books.
Amazon Verified review Amazon
Norbert Varga Aug 07, 2014
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I chose this book because I like Javascript very much, but I'm not familiar with Node.js, so it was an interesting read.The author chose the best way to teach Node.js (in fact, I think this is the best way to teach anything, and keep the reader's attention): by real-life examples. These examples are very good, they show the reader how to deal with real-life problems like interacting with a MySQL database, implementing a blog engine, implementing a REST API, and creating desktop apps.I definitely recommend this book to everyone who know Javascript well, and want to know more about Node.js.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see www.packtpub.com/support and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to www.packtpub.com/account
  • To contact us directly if a problem is not resolved, use www.packtpub.com/contact-us
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.