Routes and errors
Update and delete resources
Implement predictable update and deletion behavior without treating every action as an unrelated POST endpoint.
8 minute lesson
Use the standard method semantics when they fit. PUT /books/:id replaces the client-editable representation; DELETE removes it.
Choose and document whether PUT can create a missing resource. For this project it cannot, so a missing ID returns 404. A successful DELETE can return 204 with no response body.
app.delete('/books/:id', c => {
const index = books.findIndex(book => book.id === c.req.param('id'))
if (index === -1) return c.json({ title: 'Book not found', status: 404 }, 404)
books.splice(index, 1)
return c.body(null, 204)
})
PUT represents a full replacement of the client-editable state. Missing writable fields should therefore fail validation rather than silently retain their previous values. If the API later needs partial changes, add PATCH with a separate contract instead of making PUT mean both things.
Keep server-owned fields such as ID and creation time unchanged, and perform lookup, authorization, and mutation as one coherent operation when the database arrives. A 204 response has no body; do not attach JSON or a content type to it. Repeat the same PUT and DELETE during the exercise: replacement with the same representation should converge on the same state, while a second delete should produce the documented missing-resource response.
Add PUT and DELETE, then repeat each request to see whether its semantics remain understandable.
Lesson completed