Stop 09 · API DesignTopics · 1/12

REST API Best Practices

Part of the Backend Developer Roadmap

In short

Anyone can make an endpoint that works. A good REST API feels obvious: you can guess the next URL before opening the docs. Your frontend teammates will thank you for it.

The conventions experienced teams follow beyond the bare REST spec — consistent naming, proper status codes, predictable error shapes — that make an API pleasant to consume.

The blob character sorts parcels into a neat wall of labelled pigeonholes.

Think of it like this

Post office pigeonholes

A well-run post office has one labelled slot per area and the same rules at every counter. Nobody asks where to drop a parcel. A REST API works the same way: one clear URL per thing, and the same rules for every request.

Watch it happen

One resource, predictable answers

Client
Orders API
Database

GET /orders/42

1/7The client asks for one order. The URL names the thing (orders), not the action.

The big ideas

What you need to know

Nouns in URLs, verbs in methods

Use /orders and /orders/42. Let GET, POST, PATCH and DELETE say what you are doing.

Status codes carry meaning

200 OK, 201 created, 400 bad input, 401 not logged in, 404 missing, 500 your bug. Clients and tools trust these.

One error shape everywhere

Return errors like { error: { code, message } } on every route, so clients handle them in one place.

Consistency beats cleverness

Pick plural nouns, one JSON casing and ISO dates. Then never mix styles across endpoints.

See it in code

Walk through the code

ts
1import express from "express";2const app = express();3app.use(express.json());4 5app.get("/orders/:id", async (req, res) => {6  const order = await db.orders.find(req.params.id);7  if (!order) {8    return res.status(404).json({ error: { code: "ORDER_NOT_FOUND", message: "No such order" } });9  }10  res.json(order);11});12 13app.post("/orders", async (req, res) => {14  const order = await db.orders.create(req.body);15  res.status(201).location(`/orders/${order.id}`).json(order);16});

1/3GET on /orders/:id reads one order. The URL is the noun; the method is the verb.

db here stands for your data layer (Prisma, Knex, anything). Notice there are no verbs in the URLs at all.

Save yourself the pain

Common mistakes

Oops

URLs like /getUser, /createOrder and /deleteOrder?id=5.

Do this instead

Use /users/7 and /orders/5 with GET, POST or DELETE. The method already says the action.

Oops

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

Do this instead

Send the real status code, like 400 or 404. Clients, proxies and monitoring tools all read the code first.

Your mission

Clean up a messy API

~25 min

Quick check

A client sends a signup form with the email missing. Which response fits best?

Go deeper

  1. 1Audit an API you've built against a REST API design checklist.
  2. 2Standardize your endpoint naming (plural nouns, nested resources) across a project.
  3. 3Design a consistent error response envelope used by every endpoint.

More topics 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