Intermediate Project: A REST API with a Database
Assemble everything you have learned into one real, working service
- lay out a small Express project into layers (routes, data, auth, tests),
- persist data in SQLite with parameterised queries,
- design CRUD routes that use correct HTTP verbs and status codes,
- add validation and token authentication as middleware,
- write integration tests with the built-in test runner and Supertest.
1. What we are building, and how it fits together
Our project is a Bookshelf API: a service that keeps a list of books and lets clients create, read, update, and delete them over HTTP. That "create, read, update, delete" quartet is so common it has a name - CRUD - and it maps almost perfectly onto REST.
REST (Representational State Transfer) is a style for HTTP APIs. Its core idea: your data is a set of resources, each with a URL, and you act on them with HTTP methods. A book collection lives at /books; a single book lives at /books/42. You do not invent verbs in the URL (/getBook, /deleteBook) - the HTTP method already says what you want.
Analogy. Think of the API as a library front desk. The shelves (the database) hold the books. The desk clerk (your Express app) is the only one allowed to touch the shelves; visitors must ask the clerk. Some requests - "show me book 42" - are free for anyone. Others - "add a book", "throw one out" - require a staff badge (the auth token). And before the clerk files a new book, they check the form is filled in correctly (validation). Every layer has one job.
Here is how a single request flows through those layers:
Read the API from left to right: a request is checked, validated, handled, and only then does it reach the data. Keeping those responsibilities separate is what makes an intermediate project maintainable instead of one giant tangled file.