
If you’ve ever stared at an API and thought, “Why does this endpoint feel like it was designed by a raccoon with Wi-Fi?” — this is for you.
REST APIs have been around since the early 2000s. And yet, so many of them are still a mess. Verbs in URLs, wildcard status codes, inconsistent naming — it’s a jungle out there.
This guide will show you how to build clean, consistent, not-terrible REST APIs in modern TypeScript. Let’s start from the top.
What Even Is REST?
REST stands for Representational State Transfer, but don’t let that scare you. It just means:
- You use HTTP to work with data.
- Data is modeled as resources (things like users, posts, products).
- You use standard methods (
GET,POST, etc.) to manipulate those resources.
Think of it like this: Your API is a vending machine. The resources are snacks. The HTTP methods are the buttons.
Rule #1: Think in Nouns, Not Verbs
A bad API tries to describe actions in the URL:
POST /createUser
GET /fetchAllUsers
DELETE /removeUser/123❌ This is not RESTful. It’s just RPC with extra steps. A good REST API models resources, and lets HTTP methods do the talking:
POST /users ← Create a user
GET /users ← Get all users
GET /users/123 ← Get one user
DELETE /users/123 ← Delete user 123✔️ Clean. Predictable. Feels like browsing folders.
Rule #2: Use HTTP Methods Like a Grown-Up
Here’s the cheat sheet:
| Method | Use For |
|---|---|
| GET | Fetching data |
| POST | Creating new data |
| PUT | Replacing data |
| PATCH | Updating part of it |
| DELETE | Deleting stuff |
Example: Let’s Code a Basic User API
We’ll use TypeScript + Express — because I want to:P
import express from "express";
const app = express();
app.use(express.json());
let users: any[] = [];
app.post("/users", (req, res) => {
const { name } = req.body;
const user = { id: users.length + 1, name };
users.push(user);
res.status(201).json(user); // Created
});
app.get("/users", (req, res) => {
res.json(users); // OK
});
app.get("/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.json(user);
});
app.delete("/users/:id", (req, res) => {
const id = Number(req.params.id);
users = users.filter((u) => u.id !== id);
res.status(204).send(); // No Content
});
app.listen(3000, () => {
console.log("API listening on port 3000");
});Pro Tips
- Use plural nouns in routes (
/users, not/user) — it's standard. - Never use verbs in URLs — HTTP methods already say what you’re doing.
- Return proper status codes (more on that in Part 3).
Recap
- REST is about modeling data as resources, not actions.
- Keep your routes noun-based and consistent.
- Let HTTP methods do their job.
Coming Up Next:
Part 2: “Don’t Be Weird with URLs: RESTful Routing That Makes Sense”
We’ll tackle nested resources, versioning, and how to keep your URLs clean and human-readable.