Lesson 6 of 7
Mini Project: REST API with Persistence
Build a small API for notes that saves data to a file, using Express and the file system. No setup is needed.
// notes-api/src/index.js
// npm install express
// Run: node src/index.js
import express from 'express'
import { readFile, writeFile } from 'fs/promises'
import { existsSync } from 'fs'
import { randomUUID } from 'crypto'
const app = express()
const DB = "./notes.json"
app.use(express.json())
// Load / save helpers
async function load() {
if (!existsSync(DB)) return []
return JSON.parse(await readFile(DB, "utf-8"))
}
async function save(notes) {
await writeFile(DB, JSON.stringify(notes, null, 2))
}
// GET /notes
app.get("/notes", async (req, res) => {
const notes = await load()
const { q } = req.query
res.json(q ? notes.filter(n => n.body.includes(q) || n.title.includes(q)) : notes)
})
// GET /notes/:id
app.get("/notes/:id", async (req, res) => {
const notes = await load()
const note = notes.find(n => n.id === req.params.id)
if (!note) return res.status(404).json({ error: "Not found" })
res.json(note)
})
// POST /notes
app.post("/notes", async (req, res) => {
const { title, body } = req.body
if (!title || !body) return res.status(400).json({ error: "title and body required" })
const notes = await load()
const note = { id: randomUUID(), title, body, createdAt: new Date().toISOString() }
notes.push(note)
await save(notes)
res.status(201).json(note)
})
// PATCH /notes/:id
app.patch("/notes/:id", async (req, res) => {
const notes = await load()
const idx = notes.findIndex(n => n.id === req.params.id)
if (idx === -1) return res.status(404).json({ error: "Not found" })
notes[idx] = { ...notes[idx], ...req.body, updatedAt: new Date().toISOString() }
await save(notes)
res.json(notes[idx])
})
// DELETE /notes/:id
app.delete("/notes/:id", async (req, res) => {
const notes = await load()
const filtered = notes.filter(n => n.id !== req.params.id)
if (filtered.length === notes.length) return res.status(404).json({ error: "Not found" })
await save(filtered)
res.status(204).end()
})
app.listen(3000, () => console.log("Notes API: http://localhost:3000"))# Test with curl
curl -X POST http://localhost:3000/notes \
-H "Content-Type: application/json" \
-d '{"title":"My First Note","body":"Hello, Node!"}'
curl http://localhost:3000/notes
curl http://localhost:3000/notes?q=Hello
# Replace <id> with an actual ID from the POST response
curl -X PATCH http://localhost:3000/notes/<id> \
-H "Content-Type: application/json" \
-d '{"body":"Updated body"}'
curl -X DELETE http://localhost:3000/notes/<id>Finished reading?Mark it done to track your progress.
Tip: use the ← and → keys to move between lessons.