Build a Bookstore REST API
Build an API for managing a bookstore inventory. The API allows listing books with pagination and filtering, fetching individual books, adding new books, updating existing books, and deleting books.
Endpoints
-
GET /api/books- Query parameters:
page(optional integer, minimum 1, default 1),limit(optional integer, min 1, max 50, default 10),genre(optional string),minPrice(optional number),maxPrice(optional number). - Responds with
200 OKand JSON:json{ "data": [ { "id": "1", "title": "The Hobbit", "author": "J.R.R. Tolkien", "genre": "fantasy", "price": 14.99, "stock": 25 } ], "pagination": { "page": 1, "limit": 10, "totalItems": 1, "totalPages": 1 } } - Returns
400 Bad Requestwith{"error": "Invalid query parameters"}ifpageorlimitare not positive integers or iflimitexceeds 50.
- Query parameters:
-
GET /api/books/:id- Responds with
200 OKand the book object if found. - Responds with
404 Not Foundand{"error": "Book not found"}if no book exists with that ID.
- Responds with
-
POST /api/books- Accepts JSON body:
title(required string),author(required string),genre(required string),price(required positive number),stock(required non-negative integer). - Responds with
201 Created, aLocationheader set to/api/books/:id, and the created book object. - Responds with
400 Bad Requestand{"error": "Validation error"}if any required fields are missing, invalid, or empty strings.
- Accepts JSON body:
-
PUT /api/books/:id- Accepts JSON body replacing book fields:
title,author,genre,price,stock(all required, same validation rules as POST). - Responds with
200 OKand the updated book object. - Responds with
404 Not Foundand{"error": "Book not found"}if the book does not exist. - Responds with
400 Bad Requestand{"error": "Validation error"}on invalid payload.
- Accepts JSON body replacing book fields:
-
DELETE /api/books/:id- Responds with
204 No Contenton successful deletion. - Responds with
404 Not Foundand{"error": "Book not found"}if the book does not exist.
- Responds with
Requirements
- The store exports pre-populated books in
src/store.jsas an array. - Book IDs should be strings generated incrementally or deterministically (e.g., string representation of next auto-increment integer ID).
- Filtering by
genremust be case-insensitive exact match. minPriceandmaxPricefilters must filter books inclusively.- Pagination results must be sorted deterministically by string
idin ascending numerical order.
The setup
The files open on a skeleton whose routes answer 501. Build the endpoints the statement describes.
Your API runs here, in a sandbox in this browser with Node and Express. Run sends the visible scenarios to it, Submit sends every scenario, and the API client sends anything you like.
- src/app.js
- src/store.js
Locked files are given finished for this task and open read-only.
There is no database: the API keeps its data in memory. Every scenario starts from a fresh app with the seed data.
Follow-up: How would you implement cursor-based pagination instead of offset-based pagination to handle real-time inventory updates efficiently?
Do not install external npm packages. Use Node's built-in modules and Express. Preserve existing data in src/store.js.