Welcome to the first lesson of our course on building a Reading Tracker API with NestJS. In this lesson, we will focus on the foundation of any reading tracker: the book catalog. A well-organized catalog makes it easy for users to find, browse, and manage books. By the end of this lesson, you will know how to store book information, search for books, sort results, and paginate through large lists. These are essential features for any modern API that deals with collections of data.
In this unit we lay the catalog groundwork your API will build on later: richer book metadata, a validated CreateBookDto, a FindAllBooksDto for query parameters, and a controller/service pipeline that supports public search, sorting, and pagination on GET /books. Here we will implement these pieces end-to-end so lists are UI-ready and scalable.
Book metadata is the information we store about each book. This includes details like the title, author, total number of pages, and important dates. Here’s what each field means:
Here’s how a book is represented in our code:
By storing this metadata, we make it possible to search, sort, and display books in a meaningful way.
Here we will update the Book interface and seed array so each book carries analytics-friendly fields used throughout the course.
What changed
- Added
totalPages,optional publishDate, anduploadedAtto Book. - Seeded two books with those fields populated in ISO formats.
Why
- These fields power sorting and (later) progress/analytics.
uploadedAtmakes new items visible in lists without extra queries.
This change standardizes how books are represented and ensures any list, sort, or later aggregation has the minimal metadata it needs. Using ISO strings keeps comparisons deterministic and display-ready. Seeding a couple of books guarantees your /books endpoint always has something to return. This foundation will be used by your search/sort logic in the next steps.
Here we will update the DTO used by the admin-only POST so creation is validated at the edge.
What changed
- Required
title,author, andtotalPages(≥ 1). - Optional, strictly formatted
publishDate(ISO 8601). Why - Prevents invalid records from entering the catalog.
- Keeps later list/sort behavior predictable.
With this DTO, invalid payloads are rejected early with helpful errors. That reduces downstream null/edge handling and makes client behavior clearer. The constraints mirror the fields you just added to the model, keeping the contract between controller and service simple.
Here we introduce a single, typed DTO for all list query params on GET /books.
This DTO decouples transport concerns from your service logic and guarantees sanitized inputs reach the core. It also ensures pagination has sensible bounds, protecting performance and response sizes. The same pattern will support more advanced sorts later without changing controller signatures.
A catalog is only useful if users can find what they are looking for. In our API, we allow users to search for books by title or author using the q query parameter. This search is case-insensitive and matches any part of the title or author’s name.
We'll need the service search → sort → paginate functionality. Here’s how the search works in the service:
When a catalog grows, it’s important to help users organize and navigate the results. Our API supports sorting and pagination through query parameters.
Sorting:
Users can sort books by title, author, publishDate, or uploadedAt. They can also choose the order: ascending (asc) or descending (desc).
Here’s how sorting is handled:
Pagination:
To avoid overwhelming users with too many results at once, we use pagination. The page and pageSize parameters control which results are returned.
Example:
Suppose there are 30 books in the catalog. If a user requests /books?page=2&pageSize=10&sortBy=title&order=asc, the API will return books 11 – 20, sorted by title in ascending order.
Sample Output:
This approach keeps the catalog easy to browse, even as it grows.
For tests, use the seed credentials admin/admin. Only the catalog features are tested here: public list/search/sort/pagination and the admin-only create.
1. Public: list existing books
2. Admin login and create a couple of books
3. Public search + sorting + pagination
4. Negative tests (expect errors)
What to look for
- The public GET returns
{ items, page, pageSize, total }and respects your query params. - Admin-created books appear in subsequent GETs and can be sorted by
publishDate/.
In this lesson, you learned how to build the foundation of a book catalog in a reading tracker API. We covered how to store book metadata, search for books by title or author, sort results, and paginate through large lists. These features make your API much more user-friendly and efficient. You now have a robust, public catalog endpoint with validated creation and UI-ready listing behavior. This structure will carry forward as we add more fields and sorts. In the next unit, we’ll build on this by introducing per-user shelf/progress features and advanced sorting that reuses the same query DTO.
Now, you are ready to practice these concepts with hands-on exercises. Try searching, sorting, and paginating the book catalog yourself to reinforce what you’ve learned.
