In-Memory REST API
Hard · Express
Build the core of a REST API for books, like you would with Express and an in-memory array. Implement class BookApi with handle({ method, url, body }), which returns { status, headers, body }. headers is {} unless a rule says otherwise. The paths are /books (supports GET and POST) and /books/<id> (supports GET, PUT, PATCH and DELETE); any other path → 404 with { error: "Not Found" }. A method the path does not support → 405 with { error: "Method Not Allowed" }, checked before anything else about the request.
A book is { id, title, author, year, isbn }. Ids are numbers starting at 1 and are never reused.
Validation is used by POST and PUT, and by PATCH for the fields it contains. A body that is not a plain object → 400 with { error: "Body must be a JSON object" }. Otherwise collect all problems into { error: "Validation failed", fields: { <field>: <message> } } with status 400:
- a missing field (undefined) → "is required" (PATCH skips missing fields)
- title and author must be strings that are not empty after trimming → "must be a non-empty string"
- year must be an integer from 1000 to 2100 → "must be an integer from 1000 to 2100"
- isbn must be a string of exactly 13 digits → "must be 13 digits"
- unknown fields are ignored and not stored
Routes:
- POST /books: validate; if another book has the same isbn → 409 with { error: "ISBN already exists" }; otherwise 201 with the header Location: /books/<id> and the new book as body.
- GET /books with query options (use URLSearchParams): author keeps books whose author is equal ignoring case; sort is title, -title, year or -year (- means descending; ties are ordered by id), anything else → 400 with { error: "Invalid sort" }; page (default 1) and limit (default 10, at most 50) must be positive integers written with digits only, otherwise 400 with { error: "Invalid pagination" } (check sort first). Respond 200 with { data, page, limit, total }, where total counts the filtered books before paging. Without sort, books are ordered by id.
- GET /books/<id>: the book, or 404 with { error: "Book not found" } (also when the id is not a positive integer).
- PUT /books/<id> replaces all fields (all are required). PATCH /books/<id> changes only the given fields. For both, check in this order: 404 if the book does not exist, then 400 validation, then 409 if the isbn belongs to another book. Respond 200 with the updated book.
- DELETE /books/<id>: 204 with body null, or 404.
Return copies of your stored books, so a response does not change when the book is updated later. The driver runApi(requests) is already written; each request is [method, url, body].
Next: npm Semver Ranges