BugForge
All lessons
Databases · 04/09 6 min1 hands-on

Connect a database to an API

Wire a model into Express routes: 201 on create, 400 for bad input, 404 when nothing's there.

This is the shape of nearly every backend you'll be asked to debug: a route receives a request, a controller talks to the model, and the response carries the right status code.

POST /todos  →  createTodo(req, res)  →  Todo.create(...)  →  201 + todo
GET /todos/:id  →  getTodo(req, res)  →  Todo.findById(id)  →  200 / 404 / 400

A controller, step by step

export async function getTodo(req, res) {
  const { id } = req.params;
  if (!mongoose.isValidObjectId(id))          // 1. reject garbage early
    return res.status(400).json({ error: "bad id" });
  const todo = await Todo.findById(id);       // 2. ask the database (await!)
  if (!todo)                                  // 3. nothing there
    return res.status(404).json({ error: "Todo not found" });
  res.json(todo);                             // 4. happy path, 200
}

Notice the return before each early response. Without it the function keeps going and tries to answer twice.

Which status?

Situation Status
created something 201
found it 200
client sent bad data or a malformed id 400
valid id, no such record 404

How the tests talk to your API

The tests use supertest: request(app).post("/todos").send({ title: "x" }) fires a real request at your Express app without starting a server, then check res.status and res.body.

Your turn · 1 exercise0/1 solved

Your first database-backed API

Finish the controller: POST /todos saves a todo (201, or 400 when title is missing), GET /todos/:id returns it (404 if missing, 400 for a malformed id).

Loading editor…
Next in Databases
Updating safely