Lesson 4
Navigating the Cosmos: Implementing Routes and Middlewares in Express.js
Course Introduction and Goal

Hello, future full-stack developer! Let's learn server-side programming. Today, we're going to focus on routes and middlewares in Express.js. Our goal is to help you design efficient servers that can process complex web requests. We'll apply the lessons we learned to a full-stack application using React for our client. Let's get started!

Understanding Routes in Express

Think of routes in Express.js as routes on a map, each of which directs an HTTP request. They're defined by a URL pattern and an HTTP method (GET, POST). Express.js uses these routes to process client requests.

Path parameters are variables in the routes, while query parameters add extra data to the URL. Let's look at how to log information about stars.

For example, endpoint /api/star/:id has a path parameter of id, we can query this endpoint with an URL like /api/star/123. In contrast, query parameters are added after the URL path by adding a question mark (?) and then adding the query parameters. For example: /api/stars?type=sun has a query parameter of type with the value sun.

JavaScript
1// Defining some star data for each star 2const starData = { 3 123: { type: 'sun', name: 'Sun' }, 4 124: { type: 'planet', name: 'Earth' }, 5 125: { type: 'satellite', name: 'Moon' }, 6}; 7 8// Below endpoint can be accessed via `/api/star/<starId>`, e.g., `/api/star/123` 9app.get('/api/star/:id', (req, res) => { 10 const starId = req.params.id; // retrieving a path parameter 11 const data = starData[starId] || {}; 12 res.json(data); // respond with the information of the star with the specified ID 13}); 14 15// Below endpoint can be accessed via `/api/star?type=<starType>`, e.g., `/api/star?type=sun` 16app.get('/api/stars', function (req, res) { 17 const starType = req.query.type || ''; // retrieving a query parameter 18 const data = starData.filter(star => star.type === starType)[0] || {}; // finding the star by its type 19 res.json(data); // respond with the information of the stars with a particular type 20});
React Client Interaction with Express Server Routes

Let’s fetch data for our React client using Axios. We'll retrieve a star's data.

JavaScript
1axios.get(`/api/star/123`).then(response => { 2 const starData = response.data; // retrieve the star data from the response 3 /* Display starData on the page */ 4});

In this snippet, Axios sends a GET request to fetch data about a star with a specified ID from our server, then logs the response data.

JavaScript
1axios.get(`/api/stars`, { 2 params: { 3 type: 'sun' 4 } 5}).then(response => { 6 const starData = response.data; // retrieve the star data from the response 7 /* Display starData on the page */ 8});

In this piece of code, we request and log details about Sun stars from our server.

Middlewares: The Traffic Controllers of Express.js

Middlewares in Express.js control how your server processes requests and responses, similar to traffic controllers. Middlewares are like functions that are applied to your requests, before these requests actually get executed. For example, let’s create a middleware that logs the time of each request (before the request is actually executed):

JavaScript
1app.use(function (req, res, next) { 2 console.log('Time of request:', Date.now()); 3 next(); // proceed to the next middleware 4});

Next, let's create another middleware that logs the request method.

JavaScript
1app.use(function (req, res, next) { 2 console.log('Request method:', req.method); 3 next(); // proceed to the next middleware 4});

The middlewares are executed in the order they are defined.

Connecting Middlewares and Routes: The Untold Story

Middlewares and routes are like the yin and yang of an Express.js server - they complete each other. Together, they define how the server handles and responds to client requests.

JavaScript
1const express = require('express'); 2const app = express(); 3 4// Middlewares 5app.use(function (req, res, next) { 6 console.log('Time of request:', Date.now()); 7 next(); // go to the next middleware 8}); 9app.use(function (req, res, next) { 10 console.log('Request method:', req.method); 11 next(); // go to the next middleware 12}); 13 14// Routes 15app.get('/api/star/:id', (req, res) => { 16 const starId = req.params.id; // retrieving a path parameter 17 const data = starData[starId] || {}; 18 res.json(data); // respond with the information of the star with the specified ID 19}); 20app.get('/api/stars', function (req, res) { 21 const starType = req.query.type || ''; // retrieving a query parameter 22 const data = starData.filter(star => star.type === starType)[0] || {}; // finding the star by its type 23 res.json(data); // respond with the information of the stars with a particular type 24}); 25 26app.listen(5000); // Our server listening on port 5000

We now have an Express.js server that uses a chain of middlewares and routes to process client requests. Our middlewares log each request's timing and type, and the appropriate routes then process these requests.

Lesson Summary and Next Steps

Congratulations! We've learned about routes and middlewares in Express.js, which means we can now create servers that can manage a variety of client requests.

Try out our practice exercises that are coming up next. Then, join us for our next space voyage, where we'll explore RESTful APIs and error handling in Express.js. Until then, happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.