Reviews API design, REST conventions, and backend architecture. Use when junior builds API endpoints, Express routes, middleware, controllers, or asks "is this RESTful", "check my endpoint".
"APIs are contracts. Break them, and you break trust."
Activate this skill when reviewing:
/users not /getUsers)/api/v1/)โ app.post('/users', async (req, res) => {
// 100 lines of validation, business logic, DB queries
});
โ
app.post('/users', validateUser, userController.create);
โ const { email } = req.body;
await db.query(`SELECT * FROM users WHERE email = '${email}'`);
โ
const { email } = validateBody(req.body, userSchema);
await User.findByEmail(email); // parameterized
โ res.status(200).json({ error: 'Not found' });
โ
res.status(404).json({ error: 'User not found' });
โ catch (error) {
res.status(500).json({ error: error.message, stack: error.stack });
}
โ
catch (error) {
logger.error('User creation failed', { error, userId });
res.status(500).json({ error: 'Something went wrong' });
}
Ask the junior these questions instead of giving answers:
| Code | When to Use |
|---|---|
| 200 | Success (with body) |
| 201 | Created (after POST) |
| 204 | Success (no content, after DELETE) |
| 400 | Bad request (validation failed) |
| 401 | Unauthorized (not logged in) |
| 403 | Forbidden (logged in but not allowed) |
| 404 | Not found |
| 409 | Conflict (duplicate resource) |
| 500 | Server error (hide details from client) |
Request โ Route โ Controller โ Service โ Repository โ Database
โ
Middleware (auth, validation, logging)
| Layer | Responsibility |
|---|---|
| Route | HTTP verbs, paths, middleware chain |
| Controller | Request/response handling, calling services |
| Service | Business logic, orchestration |
| Repository | Data access, queries |
| Flag | Question to Ask |
|---|---|
| SQL in route handler | "Should data access be in a separate layer?" |
| No try/catch on async | "What happens if this fails?" |
| req.body used directly | "What if someone sends unexpected fields?" |
| Hardcoded secrets | "How would this work in production?" |
| No pagination on list endpoints | "What if there are 10,000 records?" |