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) with friendIds and a FriendRequest collection.
  • Adding a minimal accessor in DatabaseService to read/write friend requests.
  • Creating a FriendsModule that composes existing services (notably UsersService) 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:

  1. A friendIds: number[] array on each user to store confirmed friends.
  2. A FriendRequest collection to track pending/accepted/declined requests.
// src/database/mock-db.ts
export interface User {
  id: string;
  name: string;
  username: string;
  passwordHash: string; // hashed password (bcrypt)
  role: 'user' | 'admin';
  friendIds: string[]; // New: list of confirmed friend user IDs
}

export interface FriendRequest {
  id: string;
  senderId: string;
  recipientId: string;
  status: 'pending' | 'accepted' | 'declined';
}

// NEW: in-memory collection of friend requests
export const friendRequests: FriendRequest[] = [];

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:

// src/friends/friends.module.ts
import { Module } from '@nestjs/common';
import { FriendsService } from './friends.service';
import { FriendsController } from './friends.controller';
import { UsersModule } from '../users/users.module';
import { ReadingModule } from '../reading/reading.module';

@Module({
  imports: [UsersModule, ReadingModule],
  controllers: [FriendsController],
  providers: [FriendsService],
})
export class FriendsModule {}

Explanation:

  • The FriendsModule imports the UsersModule so it can access user data.
  • It provides a FriendsService for business logic and a FriendsController for handling HTTP requests.

We also need to add the FriendsModule to our main app module:

// src/app.module.ts
@Module({
  imports: [UsersModule, BooksModule, ReadingModule, AuthModule, FriendsModule],
  // ...rest of the code
})
export class AppModule {}

Why this design? The friends feature stays cohesive and reuses existing building blocks (UsersService, global auth). This keeps responsibilities clear and minimizes changes elsewhere.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal