ARTICLE

Routing and Analyzing Request Data with Node.js

From Get Programming with Node.js by Jonathan Wexler
__________________________________________________________________

Save 37% off Get Programming with Node.js. Just enter fccwexler into the discount code box at checkout at manning.com.
__________________________________________________________________

This article covers routing and how a few more Express.js methods allow you to send meaningful data to the user before building a view. We’ll also walk through collecting a request’s query string. The article ends touching on the MVC design pattern.

What is Routing?

Routing is a way for your application to determine how to respond to a requesting client. Some routes are designed simply by matching the URL in the request object. That is how you’re going to build your routes in this lesson.

Each request object has a property. You can view which URL was requested by the client with . Test this out and two other properties by logging them to your console. Add the following code in listing 1 to the code block.

Listing 1. Logging request data in main.js

console.log(req.method);  
console.log(req.url);
console.log(req.headers);

Building routes with Express.js

In Express.js, a route definition starts with your object, followed by a lowercase HTTP method and its arguments: the route path and callback function.

A route handling requests to the path should look like listing 2.

Listing 2. Express.js route

app.post('/contact', (req,res) => {    
res.send("Contact information
submitted successfully.");
});

More HTTP methods exist than and and you can learn more about them at https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol.

You can use these HTTP methods on the object because is an instance of the main Express.js framework class. By installing this package, you inherited routing methods without needing to write any other code.

Express.js lets you write routes with parameters in the path. These parameters are a way of sending data through the request. Another way is with query strings. Route parameters have a colon () before the parameter and can exist anywhere in the path. See the following example of a route with parameters in listing 3.

Listing 3. Using route parameters to indicate CSA vegetable type

app.get('/items/:vegetable', (req, res) => { ❶
res.send(req.params.vegetable); ❷
});

❶ This route expects a request made to + some vegetable name or number. For example, a request to ‘/items/lettuce’ triggers the route and its callback function.

❷ This response sends the item from the URL back to the user through the params property on the request object.

Try initializing a new project called , install Express.js, and add the code to require and instantiate the Express.js module. Then create a route with parameters and respond with that parameter as in listing 3.

Route parameters are handy for specifying specific data objects in your application.

For example, once you start saving user accounts and course listings in a database, you might access a user’s profile or specific course with and , respectively.

One last note on Express.js routes. Express.js is a type of middleware because it adds a layer between a request being received and that request being processed. This feature is great, but you may want to add your own custom middleware. You may want to log the path of every request made to your application for your own records, for example. You can accomplish this by adding a log message to every route, or by creating the middleware function in listing 4.

Listing 4. Express.js middleware function for logging request path

app.use((req, res, next) => {                  ❶
console.log(`request made to: ${req.url}`); ❷
next(); ❸
});

❶ Define a middleware function with an additional argument

❷ Log the request’s path to your terminal console

❸ Call the function to continue the chain in the request-response cycle.

What is Middleware?

According to Express.js documentation Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. The next middleware function is commonly denoted by a variable named next.

As with HTTP methods, you can create a route with which runs on every request. The difference here is that you’re adding an additional argument in the callback, the function. This middleware function allows you to run custom code on the request before it matches with any other routes in your application. Once your custom code completes, points the request to the next route that matches its path. Try adding this middleware function to your application. If a request is made to , it’s first be processed by your middleware function and then by the route you created previously.

Calling at the end of your function is necessary to alert Express.js that your code is completed. Not doing this leaves your request hanging. You can also specify a path for which you’d like your middleware function to run. For example, runs for every request made to a path starting with .

Next, we’ll talk about handling data in your routes and responding with that data.

Quick Check Exercise: QC 1 What does the Express.js method do?

Analyzing Request data

Preparing fancy and dynamic responses are important in your application, but eventually you’ll need to demonstrate the application’s ability to capture data from the user’s request.

Two main ways which we can get data from the user are:

  • through the request body in a request
  • through the request’s query string in the URL

incoming data is represented as a Buffer stream, which isn’t human readable and adds an extra step to making that data accessible for processing.

Express.js makes retrieving the request body easy with the attribute. To assist in reading the body contents (as of Express.js version 4) we’ll need to install an additional package. Go to your project folder in your command line and enter the command in listing 5.

Listing 5. Installing the package

npm install body-parser –save

is a module used for analyzing incoming request bodies. This module used to come prepackaged with Express.js. To make use of it we’ll need to require the module into your application. Notice the use of to log posted data to the console in listing 6. Add that code to your project’s .

Listing 6. Capturing posted data from the request body

const bodyParser = require('body-parser');             ❶
app.use(bodyParser.urlencoded({ extended: false })); ❷
app.use(bodyParser.json());
app.post('/', (req, res) =>{ ❸
console.log(req.body); ❹
});

❶ We require the module and assign it to a constant.

❷ With Express.js’ we specify that we’ll want to parse incoming requests which are URL-encoded (usually form post and utf-8 content) and JSON formats.

❸ creating a new route for posted data is as simple as using the method and specifying a URL.

❹ we can print the contents of a posted form with the request object and its attribute

Test this out by submitting a request to http://localhost:3000 using the curl command in listing 7.

Listing 7. Capturing posted data from the request body

curl --data "first_name=Jon&last_name=Wexler" http://localhost:3000

You should see the body logged to your server’s console window as shown in listing 8.

Listing 8. logged to console

{ first_name: 'Jon', last_name: 'Wexler' }

Now when you demo the backend code to your customer you can show them, through a mocked form submission, how data is collected on the server.

Another way we can collect data is through the URL parameters. Without the need of an additional package, Express.js lets us collect values stored at the end of our URL’s path, following a . These are called query strings, and they’re often used for tracking user activity on a site and storing temporary information about the user’s visited pages.

For example, let’s examine a sample URL in listing 9.

Listing 9. logged to console

http://localhost:3000?cart=3&pagesVisited=4&utmcode=837623

❶ This URL might be passing information about the number of items in the user’s shopping cart, the number of pages they’ve visited, and a marketing code to let the site owners know how this user found your app in the first place.

To see these query strings on the server, add to your middleware function. Now try visiting the URL in listing 8. You should see logged to your server’s console window.

Next, we’ll talk about the MVC architecture and how Express.js routes fit in that structure.

Quick Check Exercise: QC 2 What additional package is needed to parse incoming data in a request body with Express.js?

Express.js and MVC

This article has been about processing of request data within your routes. Express.js opens the door to custom modules and code to read, edit, and respond with data within the request-response cycle. To organize this growing codebase, we’re going to follow an application architecture known as MVC.

MVC architecture focuses on three main parts of your application’s functionality: models, views, and controllers. You’ve already used views in past applications to display HTML in the response. Views are that — rendered displays of data from your application. Models are classes to represent object-oriented data in your application and database. For example, in your CSA application you might create a model to represent a customer order. Within this model you’ll define what data an order should contain and the types of functions you can run on that data.

Controllers are the glue between views and models. Controllers perform most of the logic once a request is received to determine how request body data should be processed and how to involve the models and views. This should sound familiar because in an Express.js application your route callback functions act as the controllers.

To follow the MVC design pattern, you’ll move your callback functions to separate modules reflecting the purpose of those functions. For example, callback functions related to user account creation, deletion, or change go in a file called within the folder. Functions for routes that render the homepage or other informational pages can go in the , by convention. See figure 1 for the file structure your application follows.

Figure 1. Express.js MVC file structure

Figure 2 shows how Express.js is a layer over your application to handle requests, but also feeds your application’s controllers. The callbacks decide if a view should be rendered or some data sent back to the client.

Figure 2. Express.js can follow the MVC structure with routes feeding controllers

To restructure your application to adhere to this structure, follow these steps:

  • Start by creating a folder within your project folder.
  • Create a file within
  • Require your home controller file into your application by adding the following to the top of .let homeController = require(‘./controllers/homeController’);
  • Move your route callback functions to the home controller and add them to that module’s object. For example, your route to respond with a vegetable parameter can move to your home controller to look like listing 10.

Listing 10. Moving a callback to the home controller

exports.send_req_param = (req, res) => { ❶
let veg = req.params.vegetable;
res.send(`This is the page for ${veg}`);
}

❶ In we assign to the callback function. is a variable name, you can choose your own name which is descriptive of the function.

Back in we’ll change the route to look like listing 11.

Listing 11. Replacing a callback with a reference to a controller function

app.get('/items/:vegetable', homeController.send_req_param); ❶

❶ When a request is made to this path the function assigned to in the home controller’s run.

Apply this structure to the rest of your routes and continue to use the controller modules to store the routes’ callback function. With this setup, your Express.js is taking on a new form with MVC in mind.

Quick Check Exercise: QC 3 What is the role of controllers in MVC?

Summary

In this article you learned how to build routes and middleware functions with Express.js. Then you installed the package to work with Express.js in analyzing request body contents. At the end of the article you learned about MVC and how routes can be rewritten to make use of controllers in your application.

Answers to Quick Check Exercises

QC 1" The method allows you to define middleware functions you want to use with Express.js.

QC 2: The package offers a library of code for parsing incoming data to the server. Other packages act as middleware and perform similar tasks.

QC 3: Controllers are responsible for processing data by communicating with models, performing code logic, and call for a view to be rendered in a server’s response.

Hopefully, you even more interested in learning Node.js than you were at the beginning of this article. If you want to learn more about the book, check it out on liveBook here and see this slide deck.

About the author:
Jonathan Wexler has an extensive background in computer theory and web development. Having curated a Node.js curriculum as the academic director and lead developer for The New York Code and Design Academy, Jonathan has instructed multiple intensive programs in full stack development and currently works as a senior developer for Bloomberg LP.

Originally published at freecontent.manning.com.

Follow Manning Publications on Medium for free content and exclusive discounts.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store