Developing web applications with Node.js

In the previous chapter, you learned all about Node's key features that make it a great choice when writing highly-performing software and when you need to interact with a database. You'll be happy to know that Node.js is also a great choice when you want to build real-time web applications.

Node.js allows you to build modern, real-time web applications that use a module called Socket.io that implements WebSockets, allowing you to push data asynchronously from the server to the clients. This technology, combined with RethinkDB's Changefeeds, allows you to build web applications that send data to the clients in real time without all the complexity and downfalls of traditional real-time programming flows, such as continuously polling the server for updates.

When developing web applications, most languages and platforms provide you with frameworks that greatly simplify the job of writing TCP or HTTP servers. For example, the most popular framework for the Ruby programming language is Rails, whereas the most popular framework for Python is probably Django. Node.js is no exception and has several web-oriented frameworks. The most popular one is probably Express.js.

Express is a Node.js framework module that has the goal of simplifying and structuring the development of web applications, such as supporting routing of HTTP requests to the correct controller, serving static assets such as images, and rendering HTML templates.

In the following sections, we'll go over the main components that make up a real-time web application developed in Node.js using the Express.js framework and WebSockets.

Note

Developing real-time web applications is a huge topic and we can probably write dozens of books about it, thus it is impossible to condense everything in just one chapter. For this reason, instead of trying to explain all about web applications, we're going to take a practical approach and focus on what's specific for Node.js and, in particular, how RethinkDB's features can help us in the development process.

Express.js

At the heart of Express.js is Connect, a middleware framework that comes with a lot of useful features. Perhaps, the first most important thing you need to set up in an Express.js web app is the HTTP server. An Express.js HTTP server inherits from the Connect HTTP server, which, in turn, inherits from the basic Node.js HTTP server.

You maybe surprised by just how easy it is to create an HTTP server in Node.js using the Express.js framework. Take a look here:

var express = require('express');
var app = express.createServer();
app.listen(8080, function() {
    console.log("Express server listening on port 8080");
});

After the initial Express.js dependency has loaded, we create an Express.js server by calling the createServer() function. Finally, we tell our HTTP server to start listening on port 8080. As soon as we call the listen function, our web application will start listening for HTTP requests, and it will pass these requests to another important component of a Node.js web application: the router.

Routing

Probably, the most important finality of a web application is serving resources. As you can imagine, a typical web app will have to serve multiple resources; so, how do we handle different requests and serve the appropriate resource to each of them? The answer is routing.

Routing allows us to trigger different parts of an application in response to HTTP requests. For instance, get requests will probably need to be treated differently from post requests and different URLs should probably trigger different parts of the application.

If we're working on a web application that allows users to post new messages to a message board, we can define the following routes:

  • get(/messages
  • get(/message/:id
  • post(/messages
  • put(/message/:id
  • delete(/message/:id

The list we've just defined is called a routing table. This table maps HTTP methods (get, post, put, and delete) and URLs to actions defined in the web application.

Let's have a quick look at how to set up and configure routing in an Express.js app:

app.use(app.router);
app.get("/messages", function(req, res) {
    // handle the request
});
app.get("/message/:id", function(req, res) {
    // handle the request
});
app.post("/messages", function(req, res) {
    // handle the request
});

Here, we are defining three route handlers for our Express.js application. The first one is activated when the client sends a get request to the /messages URL; the second one is a dynamic route, and it is activated when the client requests a specific message via get; whereas the third handler manages post requests to the /messages URL.

As you can see, the Express.js router allows us to define both simple and dynamic routes using a very simple syntax. Now that we know how to handle requests using the router, it's time to look at how to respond to these requests using templates.

Templating

Templating is a feature that allows you to split your content from your Node.js code, making it much easier to structure your project correctly, and render dynamic web pages (views) to the browser.

There are quite a few different templating engines, but they all share the same features. Probably, the two most popular ones are Jade and EJS. In this book, we're going to use EJS as our templating and view engines.

The first thing we need to do before we start rendering views is to tell our Express.js app to use EJS. We can do so with the following code:

app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

The first line tells Express.js that our EJS view files will be in a folder called views, while the second line instructs our Express.js application to use EJS as the view engine.

Now that Express has been set up to use EJS, let's take a quick look at how templating works and how we can use EJS to render dynamic views. Create an empty file, name it index.ejs, and type the following code:

<html>
<h1><%= title %></h1>
</html>

This is a very simple example of an EJS template. When we ask Express.js to render the index view, EJS will compile this template to an HTML file, inserting the dynamic data that we pass to the render function.

Let's make this clear by looking at the code that renders the view:

app.get("/", function(req, res) {
    res.render("index", {title: "Hello, World!"});
});

This code creates a route handler that gets called when the client executes a get request on the homepage. When this happens, we call the render function, which, in turn, uses EJS to render the index view. We also pass the render function to the dynamic data, which is the title variable in this case.

When this template gets rendered, the output will be this:

Hello, World!

This is a very simple example; however, it will give you a feel of how a templating engine can simplify the process of writing HTML documents that contain dynamically generated data. We'll now look at the last component that makes up our software stack: Socket.io.

Socket.io

In previous sections, you learned how WebSockets is a technology that allows us to push data from the server directly to the client. Socket.io is a Node.js module that acts as an abstraction layer for WebSockets as it provides a server and client library that allows bidirectional communication between a web server and a browser client. Socket.io is also extremely convenient as it deals with all cross-browser compatibility issues and provides you with a clean, easy-to-use, and abstract interface for you to interact with.

If you're worried about the complexity of implementing WebSockets into your application, you'll be happy to know that Socket.io integrates perfectly with Express.js, as the module works by creating a socket object and attaching it to the HTTP server in front of Express.js.

Let's look at a typical Socket.io flow:

Socket.io

First, the Socket.io module binds to Express's HTTP server and starts listening for incoming WebSockets connections. When a connection is received, it is upgraded to a WebSockets connection and a connection event is emitted. At this point, both the client and server can send messages to each other by calling the emit() function. Socket.io also provides a convenient broadcast function that allows you to send a message to all connected clients.

As you can see from this brief introduction, Socket.io is a great cross-browser communication channel for providing real-time, bidirectional messaging between a client and a server.

Now that you've learned something about all the components that make up a Node.js web application, it's time to turn back to RethinkDB and look at how we can interact with it within our real-time web app.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.187.201