Getting MEAN with Mongo, Express, Angular, and Node
Total Page:16
File Type:pdf, Size:1020Kb
SAMPLE CHAPTER MANNING Simon Holmes Getting MEAN with Mongo, Express, Angular, and Node by Simon Holmes Chapter 5 Copyright 2016 Manning Publications brief contents PART 1SETTING THE BASELINE .................................................1 1 ■ Introducing full-stack development 3 2 ■ Designing a MEAN stack architecture 24 PART 2BUILDING A NODE WEB APPLICATION...........................51 3 ■ Creating and setting up a MEAN project 53 4 ■ Building a static site with Node and Express 80 5 ■ Building a data model with MongoDB and Mongoose 120 6 ■ Writing a REST API: Exposing the MongoDB database to the application 160 7 ■ Consuming a REST API: Using an API from inside Express 202 PART 3ADDING A DYNAMIC FRONT END WITH ANGULAR.........241 8 ■ Adding Angular components to an Express application 243 v vi BRIEF CONTENTS 9 ■ Building a single-page application with Angular: Foundations 276 10 ■ Building an SPA with Angular: The next level 304 PART 4MANAGING AUTHENTICATION AND USER SESSIONS......347 11 ■ Authenticating users, managing sessions, and securing APIs 349 Building a data model with MongoDB and Mongoose This chapter covers ■ How Mongoose helps bridge an Express/Node application to a MongoDB database ■ Defining schemas for a data model using Mongoose ■ Connecting an application to a database ■ Managing databases using the MongoDB shell ■ Pushing a database into a live environment ■ Using the correct database depending on the environment, distinguishing between local and live versions of an application In chapter 4 we ended up by moving our data out of the views and backward down the MVC path into the controllers. Ultimately, the controllers will pass data to the views, but they shouldn’t store it. Figure 5.1 recaps the data flow in an MVC pattern. For storing the data we’ll need a database, specifically MongoDB. So this is our next step in the process: creating a database and data model. 120 Building a data model with MongoDB and Mongoose 121 Data flow in an MVC pattern Holds the Processes Renders the data the data processed data Model Controller View Data flow Data flow Figure 5.1 In an MVC pattern, data is held in the model, processed by a controller, and then rendered by a view. NOTE If you haven’t yet built the application from chapter 4, you can get the code from GitHub on the chapter-04 branch at github.com/simonholmes/ getting-MEAN. In a fresh folder in terminal the following command will clone it: $ git clone -b chapter-04 https://github.com/simonholmes/getting-MEAN.git We’ll start by connecting our application to a database before using Mongoose to define schemas and models. When we’re happy with the structure we can add some test data directly to the MongoDB database. The final step will be making sure that this also works when pushed up to Heroku. Figure 5.2 shows the flow of these four steps. 1 2 3 4 Connect Define Add test Push application schemas data to to live to database and models database environment Figure 5.2 Four main steps in this chapter, from connecting our application to a database to pushing the whole thing into a live environment For those of you who are worried that you’ve missed a section or two, don’t worry—we haven’t created a database yet. And we don’t need to. In various other technology stacks this can present an issue and throw errors. But with MongoDB we don’t need to create a database before connecting to it. MongoDB will create a database when we first try to use it. 122 CHAPTER 5 Building a data model with MongoDB and Mongoose 1 Use Mongoose with Express and Encapsulating Node.js to model Express app Express app data and connect to database Database API Express Node.js AngularJS MongoDB Express Angular SPA Node.js Figure 5.3 The MongoDB database 2 Create database and using Mongoose and add data to it inside Express to model the data and manage AngularJS the connection to the database Figure 5.3 shows where this chapter will focus in terms of the overall architecture. We’ll, of course, be working with a MongoDB database, but most of the work will be in Express and Node. In chapter 2 we discussed the benefits of decoupling the data integration by creating an API rather than tightly integrating it into the main Express app. So although we’ll be working in Express and Node, and still within the same encapsulating application, we’ll actually be starting the foundations of our API layer. NOTE To follow through this chapter you’ll need to have MongoDB installed. If you haven’t done so already, you can find the instructions for this in appen- dix A. The source code of the application as it will be at the end of this chapter is avail- able from GitHub on the chapter-05 branch. In a fresh folder in terminal the following commands will clone it and install the npm module dependencies: $ git clone -b chapter-05 https://github.com/simonholmes/getting-MEAN.git $ cd getting-MEAN $ npm install 5.1 Connecting the Express application to MongoDB using Mongoose We could connect our application directly to MongoDB and have the two interact with each other using the native driver. While the native MongoDB driver is very Connecting the Express application to MongoDB using Mongoose 123 powerful it isn’t particularly easy to work with. It also doesn’t offer a built-in way of defining and maintaining data structures. Mongoose exposes most of the function- ality of the native driver, but in a more convenient way, designed to fit into the flows of application development. Where Mongoose really excels is in the way it enables us to define data struc- tures and models, maintain them, and use them to interact with our database. All from the comfort of our application code. As part of this approach Mongoose includes the ability to add validation to our data definitions, meaning that we don’t have to write validation code into every place in our application where we send data back to the database. So Mongoose fits into the stack inside the Express application by being the liaison between the application and the database, as shown in figure 5.4. Browser Database Application application MongoDB Node.js AngularJS Express Mongoose Figure 5.4 The data interactions in the MEAN stack and where Mongoose fits in. The Node/Express application interacts with MongoDB through Mongoose, and Node and Express can then also talk to Angular. MongoDB only talks to Mongoose, and Mongoose in turn talks to Node and Express. Angular will not talk directly to MongoDB or Mongoose, but only to the Express application. You should already have MongoDB installed on your system (covered in appen- dix A), but not Mongoose. Mongoose isn’t installed globally, but is instead added directly to our application. We’ll do that now. 5.1.1 Adding Mongoose to our application Mongoose is available as an npm module. As you saw in chapter 3, the quickest and easiest way to install an npm module is through the command line. We can install Mongoose and add it to our list of dependencies in package.json with one command. So head over to terminal and make sure the prompt is at the root folder of the application, where the package.json file is, and run the following command: $ npm install --save mongoose 124 CHAPTER 5 Building a data model with MongoDB and Mongoose The --save flag is what tells npm to add Mongoose to the dependency list in pack- age.json. When that command has finished running you’ll be able to see a new mon- goose folder inside the node_modules folder of the application, and the dependencies section of the package.json file should look like the following code snippet: "dependencies": { "express": "~4.9.0", "body-parser": "~1.8.1", "cookie-parser": "~1.3.3", "morgan": "~1.3.0", "serve-favicon": "~2.1.3", "debug": "~2.0.0", "jade": "~1.6.0", "mongoose": "~3.8.20" } You may have slightly different version numbers, of course, but at the time of writing the latest stable version of Mongoose is 3.8.20. Now that Mongoose is installed, let’s get it connected. 5.1.2 Adding a Mongoose connection to our application At this stage we’re going to connect our application to a database. We haven’t created a database yet, but that doesn’t matter because MongoDB will create a database when we first try to use it. This can seem a little odd, but for putting an application together it’s a great advantage: we don’t need to leave our application code to mess around in a different environment. MONGODB AND MONGOOSE CONNECTION Mongoose opens a pool of five reusable connections when it connects to a MongoDB database. This pool of connections is shared between all requests. Five is just the default number and can be increased or decreased in the connection options if you need to. BEST-PRACTICE TIP Opening and closing connections to databases can take a little bit of time, especially if your database is on a separate server or service. So it’s best to only run these operations when you need to. The best practice is to open the connection when your application starts up, and to leave it open until your application restarts or shuts down. This is the approach we’re going to take. SETTING UP THE CONNECTION FILE When we first sorted out the file structure for the application we created three folders inside the app_server folder: models, views, and controllers.