Lesson 26 +10 XP

Building CRUD Endpoints

Complete In-Memory RESTful CRUD API

Let's combine routing, status codes, query strings, and params into a complete CRUD Express resource controller.

const express = require("express");
const app = express();
app.use(express.json());

// In-memory data store
let users = [
  { id: 1, name: "Alice", role: "developer" },
  { id: 2, name: "Bob", role: "designer" }
];

// CREATE: POST /api/users
app.post("/api/users", (req, res) => {
  const { name, role } = req.body;
  if (!name || !role) {
    return res.status(400).json({ error: "Fields 'name' and 'role' are required" });
  }
  const newUser = { id: Date.now(), name, role };
  users.push(newUser);
  res.status(201).json({ status: "success", data: newUser });
});

// READ ALL: GET /api/users
app.get("/api/users", (req, res) => {
  res.status(200).json({ status: "success", results: users.length, data: users });
});

// READ ONE: GET /api/users/:id
app.get("/api/users/:id", (req, res) => {
  const user = users.find(u => u.id === Number(req.params.id));
  if (!user) {
    return res.status(404).json({ error: "User not found" });
  }
  res.status(200).json({ status: "success", data: user });
});

// DELETE: DELETE /api/users/:id
app.delete("/api/users/:id", (req, res) => {
  const userIndex = users.findIndex(u => u.id === Number(req.params.id));
  if (userIndex === -1) {
    return res.status(404).json({ error: "User not found" });
  }
  users.splice(userIndex, 1);
  res.status(200).json({ status: "success", message: "User deleted" });
});

TL;DR

  • Validate body payloads before performing create or update operations.
  • Convert string path parameters (req.params.id) to numbers if comparing with numeric IDs.