CodeBlanks Logo Icon CodeBlanks

Summary - Routing

Combine param, query and Router to write a user API.

Summary: User API

In this lesson we combine what we learned into a user API: route parameters, query parameters and express.Router together.

The API works like this: GET /users lists all users, GET /users/:id returns a single user, GET /search?q=... searches by name. The router groups user routes under /users; the search route stays at the app root. This is the skeleton of a real REST API: resource routes are grouped with a router, search is done with optional query parameters. We send JSON responses with res.json.

Combining the pieces

The API has three parts. First the router: userRouter.get("/", ...) and userRouter.get("/:id", ...), mounted with app.use("/users", userRouter). Second the search: app.get("/search", (req, res) => { ... req.query.q ... }).

In the :id route we find the user whose id matches with users.find. We convert the string parameter to a number with Number(req.params.id) because id in the users array is a number. In the /search route we take the search string with req.query.q and find users whose name contains it with users.filter. Each route returns JSON with res.json. This is the standard structure of REST APIs.

Practice Write the user API

Define const userRouter = express.Router(). Define let users = [{ id: 1, name: "Ayşe" }, { id: 2, name: "Mehmet" }]. Add userRouter.get("/", (req, res) => res.json(users)). Add userRouter.get("/:id", (req, res) => { const user = users.find(function(u) { return u.id === Number(req.params.id); }); res.json(user); }). Mount with app.use("/users", userRouter). Add app.get("/search", (req, res) => { const found = users.filter(function(u) { return u.name.includes(req.query.q); }); res.json(found); }). The server requests /users/1.

Starter code

index.js
const express = require("express");
const app = express();

// Create a user router, define an array with two users
// Send all users as JSON on the router root route
// Send a single user as JSON on the :id route
// Mount the router under /users
// Add a /search route that searches with a query
// write here

const server = app.listen(3000, () => {
  const http = require("http");
  http.get("http://localhost:3000/users/1", (res) => {
    let body = "";
    res.on("data", (c) => body += c);
    res.on("end", () => { console.log("Reply: " + body); server.close(); });
  });
});

Sample solution

index.js
const express = require("express");
const app = express();

const userRouter = express.Router();
let users = [{ id: 1, name: "Ayşe" }, { id: 2, name: "Mehmet" }];
userRouter.get("/", (req, res) => res.json(users));
userRouter.get("/:id", (req, res) => {
  const user = users.find(function(u) { return u.id === Number(req.params.id); });
  res.json(user);
});
app.use("/users", userRouter);
app.get("/search", (req, res) => {
  const found = users.filter(function(u) { return u.name.includes(req.query.q); });
  res.json(found);
});

const server = app.listen(3000, () => {
  const http = require("http");
  http.get("http://localhost:3000/users/1", (res) => {
    let body = "";
    res.on("data", (c) => body += c);
    res.on("end", () => { console.log("Reply: " + body); server.close(); });
  });
});

Expected output

Yanıt: {"id":1,"name":"Ayşe"}

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Which route returns a single user?

index.js
GET /users/5
  • GET /users/:id Correct answer
  • GET /users
  • GET /search?q=5
  • POST /users

Explanation: /users/:id returns one user via a route parameter.

2 Match each piece to its role

Term Meaning
userRouter.get('/:id') Single user
req.params.id Route id
req.query.q Search string
app.use('/users', ...) Mounts the router

All lessons in Intermediate