Every piece needed is already covered — routes, HTTP methods, route parameters, JSON bodies. This lesson combines them into a complete, working REST API: a set of URLs that let another program create, read, update, and delete data over HTTP.
REST is a set of conventions, not a library or a piece of code. The core idea: a URL identifies a resource (a product, a user, an order), and the HTTP method says what to do to it. /products/7 is always "product number 7" — whether you're reading it, replacing it, or deleting it depends on the method, not the URL.
For simplicity, this example keeps products in an in-memory array rather than a real database — the next lesson replaces this with an actual one.
const express = require('express')
const app = express()
app.use(express.json())
let products = [
{ id: 1, name: 'Laptop Stand', price: 25 },
{ id: 2, name: 'Wireless Mouse', price: 15 },
]
// READ all
app.get('/products', (req, res) => {
res.json(products)
})
// READ one
app.get('/products/:id', (req, res) => {
const product = products.find(p => p.id === Number(req.params.id))
if (!product) return res.status(404).json({ error: 'Product not found' })
res.json(product)
})
// CREATE
app.post('/products', (req, res) => {
const newProduct = { id: products.length + 1, ...req.body }
products.push(newProduct)
res.status(201).json(newProduct)
})
// UPDATE
app.put('/products/:id', (req, res) => {
const product = products.find(p => p.id === Number(req.params.id))
if (!product) return res.status(404).json({ error: 'Product not found' })
Object.assign(product, req.body)
res.json(product)
})
// DELETE
app.delete('/products/:id', (req, res) => {
products = products.filter(p => p.id !== Number(req.params.id))
res.status(204).end()
})
app.listen(3000)| Code | Meaning | Used above for |
|---|---|---|
| 200 | OK | A successful GET or PUT |
| 201 | Created | A successful POST that added something new |
| 204 | No Content | A successful DELETE — nothing meaningful to send back |
| 404 | Not Found | A requested product ID that doesn't exist |
Always check for a missing resource before working with it, as every handler above does with if (!product). Skipping that check means a request for a nonexistent ID crashes the handler trying to read a property off undefined, instead of returning a clean 404.
A real API adds more on top of this: validating that req.body actually contains what's expected before using it, authentication so not just anyone can delete a product, and — the next lesson's topic — a real database instead of an array that resets every time the server restarts.