DEV Community

Diego Liascovich
Diego Liascovich

Posted on

Implementing the Repository Pattern with Mongoose in Node.js

By Diego Liascovich

Full-Stack Developer | Microservices | Angular | Node.js

The Repository Pattern serves as an intermediary between your application's business logic and the persistence layer (like MongoDB, PostgreSQL, etc.). This abstraction makes your application:

  • Decoupled from the data source
  • Easier to test (you can mock the repository)
  • More maintainable and flexible

🧾 Real Case: User Management with MongoDB and Mongoose

We will use TypeScript with Node.js and Mongoose to implement the pattern.

πŸ“ Project Structure

src/ β”œβ”€β”€ domain/ β”‚ β”œβ”€β”€ models/ β”‚ β”‚ └── user.entity.ts β”‚ └── repositories/ β”‚ └── user.repository.interface.ts β”œβ”€β”€ infrastructure/ β”‚ β”œβ”€β”€ models/ β”‚ β”‚ └── user.model.ts β”‚ └── repositories/ β”‚ └── user.repository.ts β”œβ”€β”€ application/ β”‚ └── services/ β”‚ └── user.service.ts └── main.ts 
Enter fullscreen mode Exit fullscreen mode

1. user.entity.ts – Domain Entity

export interface User { id: string; name: string; email: string; createdAt: Date; } 
Enter fullscreen mode Exit fullscreen mode

2. user.repository.interface.ts – Repository Interface

import { User } from '../models/user.entity'; export interface IUserRepository { findById(id: string): Promise<User | null>; findAll(): Promise<User[]>; create(user: Omit<User, 'id' | 'createdAt'>): Promise<User>; delete(id: string): Promise<boolean>; } 
Enter fullscreen mode Exit fullscreen mode

3. user.model.ts – Mongoose Schema and Model

import mongoose, { Schema } from 'mongoose'; const UserSchema = new Schema({ name: String, email: String, createdAt: { type: Date, default: Date.now } }); export const UserModel = mongoose.model('User', UserSchema); 
Enter fullscreen mode Exit fullscreen mode

4. user.repository.ts – Mongoose Implementation

import { IUserRepository } from '../../domain/repositories/user.repository.interface'; import { User } from '../../domain/models/user.entity'; import { UserModel } from '../models/user.model'; export class UserRepository implements IUserRepository { async findById(id: string): Promise<User | null> { return await UserModel.findById(id).lean(); } async findAll(): Promise<User[]> { return await UserModel.find().lean(); } async create(data: Omit<User, 'id' | 'createdAt'>): Promise<User> { const created = new UserModel(data); const saved = await created.save(); return saved.toObject(); } async delete(id: string): Promise<boolean> { const result = await UserModel.findByIdAndDelete(id); return !!result; } } 
Enter fullscreen mode Exit fullscreen mode

5. user.service.ts – Business Logic

import { IUserRepository } from '../../domain/repositories/user.repository.interface'; import { User } from '../../domain/models/user.entity'; export class UserService { constructor(private readonly userRepo: IUserRepository) {} async listUsers(): Promise<User[]> { return await this.userRepo.findAll(); } async registerUser(name: string, email: string): Promise<User> { return await this.userRepo.create({ name, email }); } } 
Enter fullscreen mode Exit fullscreen mode

6. main.ts – Example Usage

import mongoose from 'mongoose'; import { UserRepository } from './infrastructure/repositories/user.repository'; import { UserService } from './application/services/user.service'; (async () => { await mongoose.connect('mongodb://localhost:27017/repository-example'); const userRepo = new UserRepository(); const userService = new UserService(userRepo); const newUser = await userService.registerUser('Padie78', 'Padie78@example.com'); console.log('User created:', newUser); const allUsers = await userService.listUsers(); console.log('All users:', allUsers); })(); 
Enter fullscreen mode Exit fullscreen mode

βœ… Benefits of This Architecture

  • Decoupling: You can easily switch the database or mock the repository.
  • Unit Testing: You can mock IUserRepository in your tests.
  • Flexibility: Your business logic is not tied to any specific DB implementation.

Top comments (0)