Book Image

Mongoose for Application Development

By : Simon Holmes
Book Image

Mongoose for Application Development

By: Simon Holmes

Overview of this book

Mongoose is all about putting the data model where it should be: in your application. You can control everything from within your application in JavaScript, eliminating the need to work with the database or a separate management system. Mongoose for Application Development is a practical, hands-on guide that takes you from installing the technology stack through the steps of developing a web application. It covers the key features of Mongoose and how to use them to rapidly develop a Node.js and MongoDB application. This book introduces the full technology stack of Node.js, MongoDB, Express, and Mongoose. It will take you through the process of building an application on this stack with a focus on how Mongoose makes the process quicker and easier. You will see how Mongoose removes a layer of complexity when dealing with MongoDB whilst giving you more control over your data from your application. You will learn how to define schemas and models for your data in JavaScript. Using these schemas and models, you will learn how to build the cornerstone of any web application that will include CRUD operations (creating, reading, updating, and deleting data). If you want to learn how to build applications quickly and efficiently using Node.js, then Mongoose and this book are ideal for you. Using practical examples throughout, Mongoose for Application Development not only teaches you about the concepts of Mongoose, but walks through how to use them to build a real-life application.
Table of Contents (18 chapters)
Mongoose for Application Development
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

The technology stack – Node.js, npm, MongoDB, and Express


The benefits of Node are making it ever more popular, and a set of compatible technologies are fast becoming the basis of a new standard development stack.

The language and the server – JavaScript and Node

For quite some time JavaScript was mainly thought of as a lightweight browser-based scripting language. Microsoft did support a JavaScript version of Classic ASP, but it was largely side-lined in favor of the VBScript version.

Fast-forward 10 years and there were some pretty impressive JavaScript-based apps on the Web, for example Gmail. The general view of JavaScript as a programming language was starting to change back then.

In 2010 a new server-side system called Node.js was starting to make waves in the Internet developer community. Node.js was a new way for using JavaScript on the server side again. And it was quick and efficient. It could make scaling a web application much more cost-effective by reducing the amount of hardware required per-site visitor or request.

By 2012 Node was one of the buzzwords of the start-up scene, and you can see why. Firstly, most Web developers have some JavaScript experience so it doesn't require you to learn a new language from scratch. This also means you can share some code between front-end and back-end, so you don't have to code the same thing twice in two different languages. An excellent example of this is form validation; you want real-time validation in the browser for a better user experience, but you also need to validate on the server side to protect your system. So you code the same thing twice. Using Node you can use the same validation script on the server side and the browser, so you only have to code it once, in JavaScript.

Second, there is the reduced cost of scaling, especially when dealing with large numbers of concurrent users. On the same hardware Node's efficiencies allow it to handle many more requests than classic stacks on Apache or IIS. That being said, adding scalability to Node is more complicated than other stacks. Unlike the others you can't just put it on a more powerful machine and set it running. By default Node will currently only run one process, using only one core of a machine. There are methods to address this issue, using a load balancer in front of several processes running alongside each other for example, and there are plans to enable future versions of Node to be able to manage this natively, directly addressing this issue.

The benefits of scalability do have a cost. The single process is a more complicated approach to server-side programming and requires a change in mindset.

Single-threaded versus multithreaded

Traditional stacks are generally multithreaded. This means that every new visitor or session is given a new thread, and these are never shared. One session's activity generally doesn't impact another, until the server resources are exhausted. For example, if Session 1 is doing a complex database write operation it may take a couple of seconds, but Session 2 continues running oblivious to this.

Node is single-threaded. This means that every visitor or session is added to that one thread. So it is possible for a two-second database write operation to hold up every other user for two seconds. Multiply this by just 10 users and you've got a big problem on your hands.

Addressing this requires a different way of coding.

Blocking versus non-blocking code

In the traditional stack, the approach to coding would be one step after the other, as in the following steps:

  1. First, take the data.

  2. Then write this data to the database.

  3. Send a confirmation message.

  4. Wait for the next request.

This is blocking code, as you can only do one thing at a time. This is fine in the multithreaded stack, as you're only ever responding to one person's requests.

In the single-threaded stack, you may have to respond to several people's requests at the same time, so you can't afford to be stuck doing time-consuming operations or waiting for someone else to do something. To do this, the approach to coding becomes more like the following:

  1. You give this data to someone.

  2. They write this data to the database.

  3. When they are done, they send a confirmation message; if this isn't something they can do, then they add it to your request list.

  4. You're going to take the next request.

This is non-blocking code. You can only do one at a time. So you're getting someone else to do something for you, and telling them what to do when they have finished. You can then deal with the next request coming in without any delay.

JavaScript callbacks

The way to code this in JavaScript is to use callbacks. Most JavaScript coders start using them before they even know it, particularly anybody who uses libraries such as jQuery.

Take the basic jQuery document.ready method as shown in the following:

$(document).ready(function() {
  console.log("document ready");
});

This is an event driven callback. The $(document).ready() part is a method function of jQuery, and we are sending it a function function() that it can run at the appropriate time. So we are saying "Hi ready, here is what I want you to do once the document is ready, I'll leave it up to you to decide when that is". The callback function we are using in this example is the following code snippet:

function() {
  console.log("document ready");
}
Running the callback

The jQuery .ready() function is pretty complicated, so we're not going to look at that here. However, the construct is very useful to understand. Look at the following code snippet:

ready = function (callback) {
  // do something
  // do something else
  // ....
  // and so on
  callback();
};

So ready itself is a function, and this function accepts one parameter callback. The callback parameter is generally an anonymous function, like the one we looked at earlier. A very important point to note is that callback now exists in the scope of the ready function. This means that your callback function has access to any variables or objects created in the ready function.

A Node.js example

Now consider the following standard Node "hello world" example:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {
    'Content-Type': 'text/plain'
  });
  res.write('Hello world');
res.end();
})
listen(8888, '127.0.0.1');

Look familiar? This is sending a callback to the http.createServer method function. See how the parameters—req and res—are being sent to the callback function even though they haven't been defined or created anywhere. This works because the http.createServer function will create these objects before calling this callback function that will use them.

The database – MongoDB

MongoDB has become the main database of choice for working with Node. Note that there are Node drivers for many other databases, including MySQL, Microsoft SQL Server, Reddis, PostgreSQL, CouchDB, and more.

MongoDB is popular as it is fast and flexible with excellent community support. It is a document-oriented database, fitting in somewhere between Key-Value stores and traditional relational databases. Despite being a document store, MongoDB also enables rich querying and secondary indexing of documents, setting it apart from other databases and making it a very powerful option.

MongoDB stores documents as BSON, which is effectively binary-encoded JSON. When you run a query you get a JSON object returned (or a string in JSON format, depending on the driver). Look at the following code snippet for example:

{ "_id" : ObjectId("4ffbc45c35097b5a1583ad71"), "firstname" : "Simon", "lastname" : "Holmes }

So, a document is a set of keys (for example, firstname) and values (for example, Simon). The _id entry is a unique identifier that the underlying MongoDB driver will—by default—create for each new document.

If you are more experienced with relational databases, it may help you to think of a document as a bit like a row in a table. In this analogy, the key can be thought of as a column. An important difference is that each document doesn't have to contain the exact same set of keys, and there is no direct need to have keys with empty values taking up space.

A collection of documents is called a collection. The closest analogy is a table. So in your database you could well have multiple collections, such as a users collection, posts collection, and stats collection.

MongoDB is also extremely scalable, with many built-in capabilities for distributing across multiple servers, without compromising speed or data integrity.

With everything combined, it makes MongoDB a great playmate for Node.

The framework – Express

Express is a web application framework for Node.

When you create a Node project, you have to do a lot more groundwork than you might be used to. Until you create it, there isn't even a web server. Then you have to deal with serving static files in a non-blocking way, figure out the routing mechanism, view engine, session management, and so on.

Or you can create an Express project and let it do all of this for you, in a tried-and-tested way. At the end of this chapter, we'll see how easy it is to set up an Express project.

Note that Express is not required to build a Node application, but it is a great starting point for building web applications.