Step 3: Create to-dos with POST
To create a to-do the client sends a JSON body. Reading a request body in Node is asynchronous: the data arrives in chunks. A readBody helper collects them and parses the JSON, returning a promise so the route can simply await it.
ExampleNode.js
const http = require("http");
const todos = [];
let nextId = 1;
function send(res, status, data) {
res.writeHead(status, { "Content-Type": "application/json" });
res.end(JSON.stringify(data));
}
function readBody(req) {
return new Promise((resolve, reject) => {
let raw = "";
req.on("data", (chunk) => (raw += chunk));
req.on("end", () => {
try {
resolve(raw ? JSON.parse(raw) : {});
} catch (err) {
reject(new Error("Invalid JSON"));
}
});
});
}
async function handle(req, res) {
if (req.method === "GET" && req.url === "/todos") return send(res, 200, todos);
if (req.method === "POST" && req.url === "/todos") {
const body = await readBody(req);
const todo = { id: nextId++, title: body.title, done: false };
todos.push(todo);
return send(res, 201, todo);
}
send(res, 404, { error: "Not found" });
}
// ---- demo: start on a free port, make a few requests, stop ----
const server = http.createServer(handle);
server.listen(0, async () => {
const base = `http://localhost:${server.address().port}`;
const call = async (method, path, body) => {
const res = await fetch(base + path, { method, body: body ? JSON.stringify(body) : undefined });
const text = await res.text();
console.log(method, path, "->", res.status, text || "(empty)");
};
await call("POST", "/todos", { title: "Learn Node" });
await call("POST", "/todos", { title: "Build an API" });
await call("GET", "/todos");
server.close();
});Output
POST /todos -> 201 {"id":1,"title":"Learn Node","done":false}
POST /todos -> 201 {"id":2,"title":"Build an API","done":false}
GET /todos -> 200 [{"id":1,"title":"Learn Node","done":false},{"id":2,"title":"Build an API","done":false}]Each new to-do gets the next id, done: false, and the response status is 201 Created. The list now shows both.
Quick check
Why does readBody return a promise?
Finish the quick check (and any code exercise) to complete this lesson, or mark it done yourself.
Tip: use the left and right arrow keys to move between lessons.