Better Programming

Advice for programmers.

Follow publication

Implementing a Generic Repository Pattern Using NestJS

Generic Repository — A NestJS and Mongoose implementation

Photo by eswaran arulkumar on Unsplash

Repositories are classes or components that encapsulate the logic required to access data sources. They centralize common data access functionality, providing better maintainability and decoupling the infrastructure or technology used to access databases from the domain model layer. — Design the infrastructure persistence layer

Abstracting our data access layer will decouple our application business logic from implementation details such as mongo db/sql data access code.

Frameworks changes such as DB framework change shouldn’t affect our core services, they should be transparent to our business logic code.

Our Services should be dependent only on abstraction and not on implementation. The same goes for data services.

for example, we have a books store microservice. we have an “add new book” use case, in this use case we use the book repository in order to add new book. we don’t care about specific DB implementation and we don’t want to be bound to any DB.

Depend On Abstraction

You can find all the code with full examples in this repo

Our Entities for Author, Genre and Book are:

Abstraction

First, let’s create our abstractions:

The code for AbstractRepository class is given below:

  • You can add as many functionalities as you need.
  • T represent each entity

The code for AbstractDataServices class is given below:

  • We expose 3 repositories, one for each business entity.
  • Each repository expose all the generic repository functions

So these are our abstractions, our business services can work with them without any implementation.

now it is time to add an implementation, in this article we will implement our data services with mongoose.

MongoDb Implementation

Our MongoDB implementation will be wrapped inside a module and we will expose only abstraction.

Abstract Implementation

We need to implement:

  • Mongo Model — with all mongo specifications
  • Our generic repository — connected to mongo
  • data services- expose our mongo repositories

Model

First, let’s create our entities, they will be decorated with mongoose decorators

Mongo Generic Repository

Let’s implement our mongo generic repository

  • Simple mongo Implementation.
  • populateOnFind will give us the ability to populate our model with connected entities

Mongo Data Services

Here we need to create our repositories and expose them to our consumers

Mongo Data Services Module

In this module, we will:

  • Add the connection to the MongoDB
  • Tell our DI engine to create MongoDataServices each time a class asks for IDataServices

Main Data Services Module

This module is not a must, but I like to create it because it hides any specific implementation from our main module

Plug The Module To Our Main Application

  • Using our early created DataServiceModule we don’t see any mongo implementation stuff here, we are only adding the DataServiceModule.

Let’s Take this beauty for a ride

Now let’s use our shiny new data services in our application.

For example, let's use it in our books service for fetching books and adding new books to our DB.

  • We inject IDataServices to our service
  • Our use case logic doesn’t depend on any DB implementation, only on abstraction.
  • Changing our DB provider doesn’t affect our use case code at all.

Let’s say we want to change our DB provider, all we need to do is:

  • Create a new DB module, including : GenericRepository, DataServices
  • Consume the new module in the DataServicesModule

That’s it, no other change in our app. Your boss will be happy :)

Repository pattern is a great way to decouple your app from external DB frameworks, and generic repositories reduce the amount of code you need to write in order to accomplish it.

Next Steps

You can read more about implementing a clean architecture in your NestJs application in an article I wrote on the subject— Clean Node.js Architecture — With NestJs and TypeScript

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Royi Benita, Senior Full Stack Developer At Armis
Royi Benita, Senior Full Stack Developer At Armis

Written by Royi Benita, Senior Full Stack Developer At Armis

Senior Full Stack Developer. Enthusiastic about new technologies and architecture. More about me: www.linkedin.com/in/royi-benita-224a3014

Responses (6)

Write a response