Design a clean REST API with the right HTTP methods, the right status codes, and validation of request bodies.
Open this lesson in KodokonA REST API exposes resources (users, tasks, orders) manipulated with HTTP methods: GET to read, POST to create, PUT or PATCH to update, DELETE to remove. The professional convention: plural nouns, never verbs in the URLs. You write POST /tasks, not /createTask. Let's build a small task API, in memory for now.
import express from "express";
const app = express();
app.use(express.json());
const tasks = [
{ id: 1, title: "Review the module", done: false }
];
app.get("/tasks", (req, res) => {
res.json(tasks);
});
app.listen(3000);The line app.use(express.json()) is essential: without it, req.body is undefined for any JSON request. On creation, always validate the input, respond with 201, and return the created resource: this lets the client retrieve the id generated by the server.
app.post("/tasks", (req, res) => {
const { title } = req.body;
if (!title) {
return res.status(400).json({
error: "The title field is required"
});
}
const task = {
id: tasks.length + 1,
title,
done: false
};
tasks.push(task);
res.status(201).json(task);
});Remember the codes you'll use every day: 200 successful read or update, 201 resource created, 204 success with no content (deletion), 400 invalid request, 404 resource not found, 500 server error. The rule: with 4xx, the client made a mistake; with 5xx, it's your code that failed.
app.delete("/tasks/:id", (req, res) => {
const id = Number(req.params.id);
const index = tasks.findIndex((t) => t.id === id);
if (index === -1) {
return res.status(404).json({
error: "Task not found"
});
}
tasks.splice(index, 1);
res.status(204).end();
});req.body stay undefined for a JSON request?app.use(express.json())app.use(express.static(...))app.listen(3000)title field. What is the API's correct reaction?