Skills101

Web Development · Lesson 12 of 12 · Updated ·

Node.js, Express and REST APIs — Build Your First Backend

Node.js runs JavaScript outside the browser — on servers. Express is a small framework that makes building web servers and REST APIs easy.

A React app calls fetch, the Express API handles GET /api/courses, queries the database and returns rows as JSON; the table lists GET, POST, PUT and DELETE routes for /api/courses

1. Node.js basics

const fs = require("fs");
const path = require("path");
const os = require("os");

const file = path.join(os.tmpdir(), "skills101-demo.txt");
fs.writeFileSync(file, "Hello from Node");
console.log(fs.readFileSync(file, "utf8").toUpperCase());
fs.unlinkSync(file);
console.log(typeof process.version === "string" ? "running on Node" : "?");
HELLO FROM NODE
running on Node
  • npm installs packages: npm init -y, then npm install express.
  • package.json lists your dependencies and scripts.

2. Your first Express API

// server.js
const express = require("express");
const app = express();
app.use(express.json());                     // parse JSON request bodies

let courses = [
  { id: 1, title: "DSA in Java", price: 4999 },
  { id: 2, title: "SQL Basics", price: 0 },
];

app.get("/api/courses", (req, res) => {
  const { maxPrice } = req.query;             // ?maxPrice=1000
  const list = maxPrice ? courses.filter((c) => c.price <= Number(maxPrice)) : courses;
  res.json(list);
});

app.get("/api/courses/:id", (req, res) => {
  const course = courses.find((c) => c.id === Number(req.params.id));
  if (!course) return res.status(404).json({ error: "Course not found" });
  res.json(course);
});

app.post("/api/courses", (req, res) => {
  const { title, price } = req.body;
  if (!title || typeof price !== "number") {
    return res.status(400).json({ error: "title and numeric price are required" });
  }
  const course = { id: courses.length + 1, title, price };
  courses.push(course);
  res.status(201).json(course);
});

app.delete("/api/courses/:id", (req, res) => {
  courses = courses.filter((c) => c.id !== Number(req.params.id));
  res.status(204).end();
});

app.listen(3000, () => console.log("API on http://localhost:3000"));

Run with node server.js, then open http://localhost:3000/api/courses.

PartExampleRead with
Route param/api/courses/7req.params.id
Query string/api/courses?maxPrice=1000req.query.maxPrice
JSON body{ "title": "React" }req.body.title

3. REST design rules

  • Nouns in URLs, HTTP methods as verbs: GET /courses, not /getCourses.
  • Plural resources: /courses, /courses/7, /courses/7/lessons.
  • Correct status codes: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Server Error.
  • Return JSON consistently, including errors ({ "error": "…" }).

4. Middleware

Middleware are functions that run before your route handler — for logging, authentication, parsing:

function logger(req, res, next) {
  console.log(req.method, req.url);
  next();                        // pass control to the next middleware/route
}

function requireLogin(req, res, next) {
  if (!req.headers.authorization) return res.status(401).json({ error: "Please log in" });
  next();
}

app.use(logger);
app.post("/api/enquiries", requireLogin, (req, res) => { /* … */ });

5. Connecting a database

In real apps, replace the in-memory array with a database using a library or ORM:

  • PostgreSQL / MySQL → pg, mysql2, or Prisma (what Skills101 uses)
  • MongoDB → Mongoose
// with Prisma (example)
app.get("/api/courses", async (req, res) => {
  const courses = await prisma.course.findMany({ where: { published: true } });
  res.json(courses);
});

6. Security and deployment checklist

  • Validate every input on the server (types, lengths, formats).
  • Never build SQL by joining strings — use parameterised queries / an ORM (prevents SQL injection).
  • Store passwords hashed (bcrypt/argon2), never plain.
  • Keep secrets in environment variables (process.env.DATABASE_URL), not in code or GitHub.
  • Enable CORS only for your own frontend's domain.
  • Deploy on Render, Railway, a VPS with nginx + PM2, or similar.

Common mistakes

  • Forgetting app.use(express.json()), so req.body is undefined.
  • Sending a response twice (missing return before res.status(...)).
  • Returning 200 for errors.

Quick recap

  • Node runs JS on the server; npm manages packages.
  • Express: app.get/post/put/delete(path, handler), req.params, req.query, req.body, res.status().json().
  • REST: nouns + HTTP verbs + correct status codes + JSON.
  • Middleware with next(); validate input, hash passwords, use env variables.

Practice what you learned

📝 Quiz: Node, Express and REST5 questions · instant answers & explanations · +10 XP · counts towards your free certificateTake the quiz →