Skip to content

How to Add a Route to an Express Server in Node.js

Routing determines how an application’s endpoints (its URLs) handle requests sent by clients. Routing combines HTTP methods (GET, POST, etc.) and URL paths to run handler functions in response to a request. It’s a core concept of Node’s Express and essential to building APIs and web applications with the framework.

By the end of this tutorial, you should be able to:

  • Understand how Express applications define routes
  • Create routes that respond to specific HTTP verbs

Goal

Understand how to add a route to an express server in Node.js, and how routing works in Express to connect HTTP requests with application logic. Also, learn how to use router instances to organize routes into self-contained modules.

Prerequisites

Watch: How to Add a Route to an Express Server

Routing

Routing aims to describe what code needs to be run in response to a request that the server received. This is typically done based on the combination of the pathname and the HTTP Method associated with the request.

For example, if a GET request is received for the path /home, send back the HTML for the homepage. Or if a POST request is sent to /products, create a new product listing.

Consider the following example route:

const express = require("express");
const app = express();
app.get("/test", (req, res) => {
res.send("ok");
});

In the above example we have the following pieces:

  • app — an instance of an Express application
  • app.get — the HTTP request method this route responds to (GET in this example). Can be any of the HTTP request methods
  • "/test" — the URL path for this route
  • (req, res) => {} — the handler function which runs in response to a request that matches the method and path

These are the basic components that make up a route.

Route parameters

Routes can accept dynamic values within a path which can be accessed from the req object. These named URL segments are called “parameters”.

app.get("/product/:id", (req, res) => {
console.log("Requesting product ", req.params.id);
// respond with information for the requested product
});

Adding a colon (:) before a value in a route’s path will store the value in req.params under the parameter’s name on the request object. If a request is made to /product/1234 with the above code, 1234 would be accessible through req.params.id.

This is very useful for creating dynamic routes that accept a piece of information in the path that we need to use in the request handler. In the above example, you could use the id to look up information for a specific product.

Router instance

So far we’ve only looked at creating routes on the main Express app instance. Express exposes a Router instance which helps us create modular routes and better organize our code. Once your application begins to grow, it makes sense to organize your routes into individual files and export a single Router instance from the file.

A Router instance is similar to an Express app instance, but it is more isolated. The middleware and routes we apply to it will be scoped to the Router instance, instead of the entire application. You can mount a Router instance to the overall app by passing the instance to app.use, optionally appending a path to all the routes registered with the Router instance.

Here’s an example of a modular Express application which has a main app.js file and a file for each collection of routes:

routes/product.js file

const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
// get all products
});
router.get("/:id", (req, res) => {
// get a product by id
});
router.post("/", (req, res) => {
// create product
});
// etc.
module.exports = router;

routes/user.js file

const express = require("express");
const router = express.Router();
router.get("/:id", (req, res) => {
// get user by id
});
router.post("/", (req, res) => {
// create user
});
// etc.
module.exports = router;

app.js file

const express = require("express");
const app = express();
const productRouter = require("./routes/product");
const userRouter = require("./routes/user");
app.use("/product", productRouter);
app.use("/user", userRouter);

Each route file is exporting its own instance of an Express Router, and the main app.js requires those routes and registers them under a root URL path. The route to get a user by id becomes /user/:id, because it was mounted under the /user path with the application.

You can learn more about using Router instances at the Express docs for Router.

Recap

In this tutorial we covered the basics of defining routes with Express. We also covered creating routes that have a dynamic parameter as part of the URL path, which can be accessed when responding to the request. Finally, we learned how to use Router instances to organize our routes into self-contained modules.

Further your understanding

  • How do route parameters differ from query strings?
  • If you wanted to serve HTML pages as well as a JSON API from the same Express server, how might you organize your project and routes in order to keep the two functions of your server separate?

Additional resources