Creating the Friends Module
Introduction: Why Friendships Matter in Our App
Welcome to the first lesson of the course. In this lesson, we’ll introduce user friendships to the reading tracker. Friendships enable users to connect and motivate each other by sharing progress. By the end, you’ll model friendships in the in-memory store, create a dedicated friends module, and implement a secure endpoint for sending friend requests that uses the authenticated user from the JWT (no trusting IDs in the body).
Quick Recap: Project Structure and Setup
Our API already has users, books, and reading features wired through modules and services, plus a global JWT auth guard (requests are protected by default; public routes opt-out via @Public() where used). We’ll integrate friendships by:
- Extending the in-memory data model (
mock-db.ts) withfriendIdsand aFriendRequestcollection. - Adding a minimal accessor in
DatabaseServiceto read/write friend requests. - Creating a
FriendsModulethat composes existing services (notablyUsersService) and derives the sender from@CurrentUser().
No extra per-route guards are needed because the global guard is already active.
Modeling Friendships: Data Changes
To support friendships, we need two additions:
- A
friendIds: number[]array on each user to store confirmed friends. - A
FriendRequestcollection to track pending/accepted/declined requests.
Also ensure seeded users include friendIds: [] by default, so new friendships can be recorded
Building the Friends Module
Next, we will create a new module called FriendsModule. This module will handle all friendship-related logic, including sending and managing friend requests.
Here is how we set up the module, controller, and service:
Explanation:
- The
FriendsModuleimports theUsersModuleso it can access user data. - It provides a
FriendsServicefor business logic and aFriendsControllerfor handling HTTP requests.
We also need to add the FriendsModule to our main app module:
Why this design? The friends feature stays cohesive and reuses existing building blocks (UsersService, global auth). This keeps responsibilities clear and minimizes changes elsewhere.
