Stop 05 · Backend with Node.js & ExpressProjects · 1/2

REST API Server

Part of the Full Stack Developer Roadmap

In short

Your first real backend: a REST API with a few resources that any frontend can call. No database yet, just clean routes, proper status codes and JSON you'd be proud to show in an interview.

A standalone REST API with a handful of resources — practice for routing, middleware and response design, built before wiring it up to a database in the next phase.

The mascot runs a cycle rental stand and hands a bicycle to a customer.

Think of it like this

Running a cycle rental stand

Your stand has cycles. People ask to see all cycles, check one, add a new one to the fleet or retire a broken one. Each request is a clear action on one kind of thing. A REST API is the same: resources, plus a fixed set of actions on them.

Watch it happen

Build plan

Plan routes
Express app
Routers
Handlers
Errors
Test

1/6Write the routes on paper first: GET, POST, PATCH, DELETE for /api/cycles and /api/rentals.

The big ideas

What you need to know

Nouns in URLs, verbs in methods

Use /api/cycles with POST, not /api/createCycle. The method already says what you're doing.

Honest status codes

201 for created, 204 for deleted, 400 for bad input, 404 for missing. Your frontend will branch on these.

Same error shape everywhere

Always reply { error: "..." } on failure. The React side can then show errors with one helper.

Allow your frontend with CORS

A React app on port 5173 calling port 4000 needs CORS enabled for that origin, or the browser blocks it.

See it in code

Walk through the code

js
1import { Router } from "express";2const router = Router();3let cycles = [{ id: 1, model: "Blue 26-inch", rented: false }];4 5router.get("/", (req, res) => res.json(cycles));6router.get("/:id", (req, res) => {7  const cycle = cycles.find((c) => c.id === Number(req.params.id));8  cycle ? res.json(cycle) : res.status(404).json({ error: "Cycle not found" });9});10router.post("/", (req, res) => {11  const cycle = { id: Date.now(), model: req.body.model, rented: false };12  cycles.push(cycle);13  res.status(201).location(`/api/cycles/${cycle.id}`).json(cycle);14});15router.delete("/:id", (req, res) => { cycles = cycles.filter((c) => c.id !== Number(req.params.id)); res.status(204).end(); });16export default router; // in app.js: app.use("/api/cycles", router)

1/4A Router for one resource, with an in-memory array standing in for the database.

One resource, four actions. Copy this shape for rentals and you have a working API.

Save yourself the pain

Common mistakes

Oops

Returning 200 with { success: false } when something fails.

Do this instead

Use the real status code. fetch, logs and monitoring tools all read the status, not your JSON flag.

Oops

Letting a thrown error send Express's default HTML error page to your React app.

Do this instead

Add one error-handling middleware at the end that logs the error and returns JSON with status 500.

Your mission

First milestone: cycles resource

~45 min

Quick check

A client sends DELETE /api/cycles/5 and it succeeds. What's the cleanest response?

Go deeper

  1. 1Design and implement at least 2 resources with full CRUD routes.
  2. 2Use consistent status codes and response shapes across every endpoint.
  3. 3Test every endpoint with Postman before connecting a frontend to it.

More projects at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge