The Bookshelf API

The Bookshelf API You Will Build

Bookshelf is a catalog a reader can search and review: four resources, a handful of endpoints, and every problem a real API has — pagination, validation, authentication, ownership rules, rate limits and documentation.

The core Bookshelf endpoints, completed in The Bookshelf API
Method and path Does Auth
GET /api/books List books, paginated and filterable public
GET /api/books/:id One book with its author public
POST /api/books, PATCH /api/books/:id Add or update a book editor
POST /api/books/:id/reviews Post a review any user
POST /api/auth/login Exchange credentials for tokens public

Every route reaches data through one object, never through a driver call:

The store interface every route is written againstShell
export const bookStore = {
  async list({ limit, offset, q }) { /* ... */ },
  async get(id) { /* the book, or null */ },
  async create(input) { /* the created book */ },
  async update(id, patch) { /* the updated book, or null */ }
};

Through this chapter the implementation behind that object is an array in memory, which keeps every example runnable with no database installed and the test suite instant. In MongoDB you write a second implementation with the same four methods backed by Mongoose 243,355 models, swap it in data/index.js, and every route, controller and test keeps working untouched; Next.js then calls the running API from Next.js 10,514 server components. Adopt the pattern even where you will never change databases: the moment a route calls the driver directly, your HTTP and persistence layers are welded together and neither can be tested alone.