Building a REST API
REST (Representational State Transfer) is the most widely-used API design style. A RESTful API maps resources to URL paths and uses HTTP methods to represent CRUD operations.
1 REST Design Principles
- Resources & URLs: Resources are nouns (not verbs):
/users,/products/:id,/orders/:id/items. - HTTP Methods: GET (read), POST (create), PUT/PATCH (update), DELETE (remove).
- Status Codes: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Server Error.
- Stateless: Each request must carry all information needed to process it (auth tokens, params).
2 Complete REST API Structure
JavaScript — Complete CRUD API
const express = require('express');
const router = express.Router();
let books = [
{ id: 1, title: 'Node.js in Action', author: 'Manning', year: 2017 }
];
let nextId = 2;
// GET /books — list all
router.get('/', (req, res) => {
const { author } = req.query;
const result = author
? books.filter(b => b.author.toLowerCase().includes(author.toLowerCase()))
: books;
res.json({ data: result, count: result.length });
});
// GET /books/:id — get one
router.get('/:id', (req, res) => {
const book = books.find(b => b.id === Number(req.params.id));
if (!book) return res.status(404).json({ error: 'Book not found' });
res.json(book);
});
// POST /books — create
router.post('/', (req, res) => {
const { title, author, year } = req.body;
if (!title || !author) return res.status(400).json({ error: 'title and author required' });
const book = { id: nextId++, title, author, year: year || new Date().getFullYear() };
books.push(book);
res.status(201).json(book);
});
// PATCH /books/:id — partial update
router.patch('/:id', (req, res) => {
const book = books.find(b => b.id === Number(req.params.id));
if (!book) return res.status(404).json({ error: 'Book not found' });
Object.assign(book, req.body);
res.json(book);
});
// DELETE /books/:id
router.delete('/:id', (req, res) => {
const idx = books.findIndex(b => b.id === Number(req.params.id));
if (idx === -1) return res.status(404).json({ error: 'Not found' });
books.splice(idx, 1);
res.status(204).send();
});
module.exports = router;
3 Code Challenge
Challenge: Add input validation middleware using a package like
express-validator to ensure the POST /books route validates that year is a number between 1900 and the current year.