Skip to main content

Repositories

The repository pattern provides an abstraction layer for data access, encapsulating CRUD (Create, Read, Update, Delete) operations within repository classes. These repositories act as intermediaries between the business logic and data mapping layers, using ORMs like TypeORM, Prisma or Sequelize to interact with the database.

Goals and benefits

The main goal of the repository pattern is to separate business logic from data access logic. This allows developers to write code that is more focused on the business requirements of the application, rather than the technical details of how data is stored and accessed.

  • Separation of Concerns: It decouples business logic from data access logic, enabling developers to focus on business rules without worrying about database operations.
  • Maintainability: Centralizes data access logic within repositories, simplifying maintenance and updates to data storage implementations.
  • Abstraction: Hides the complexities of the data layer from the rest of the application, providing a simplified and consistent interface for data operations.
  • Testability: Makes testing easier by allowing the use of mock repositories or in-memory databases to simulate data persistence.

Implementation example

In the following example, we will create a simple repository pattern implementation using TypeScript. We will define a base repository interface and class, as well as a concrete repository class for a User entity.

Base repository interface

interface IBaseRepository<T> {
create(item: T): T | null;
update(item: T): T | null;
delete(id: string): boolean;
find(id: string): T | null;
findAll(): T[];
}

Base repository class

@provide(BaseRepository)
class BaseRepository<T> implements IBaseRepository<T> {
// Implement the interface methods here
}

Specific repository class

@provide(UserRepository)
class UserRepository extends BaseRepository<User> {}

The above example demonstrates the simplicity of creating a base repository that can be extended for specific entities like User.

Repositories vs providers

While repositories focus on data interaction, providers in ExpressoTS typically offer functionalities such as environment validation or logging. Keeping repositories and providers distinct ensures clean separation and adheres to the single responsibility principle.

In ExpressoTS, repositories are housed within a dedicated "repositories" folder, distinguishing them from the "providers" folder. This structural choice emphasizes their distinct roles and facilitates a modular codebase.

info

This separation happens only in the opinionated template. For the non opinionated template, you can structure your codebase as you see fit.


Support us ❤️

ExpressoTS is an MIT-licensed open source project. It's an independent project with ongoing development made possible thanks to your support. If you'd like to help, please read our support guide.