Ответ
В контексте ORM (Object-Relational Mapping) для Node.js, репозиторий — это паттерн проектирования, который абстрагирует логику доступа к данным. Он действует как посредник между бизнес-логикой приложения и слоем данных (например, базой данных), предоставляя коллекцию-подобный интерфейс для работы с сущностями.
Основная цель: инкапсулировать все операции выборки, сохранения и фильтрации данных для конкретной сущности (например, User, Product) в одном месте.
Пример реализации репозитория с TypeORM (популярная ORM для Node.js/TypeScript):
- Определение сущности:
// user.entity.ts import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity() export class User { @PrimaryGeneratedColumn() id: number;
@Column() email: string;
@Column() isActive: boolean; }
2. **Создание кастомного репозитория:**
```typescript
// user.repository.ts
import { EntityRepository, Repository } from 'typeorm';
import { User } from './user.entity';
@EntityRepository(User)
export class UserRepository extends Repository<User> {
// Кастомный метод для поиска активных пользователей
async findActiveUsers(): Promise<User[]> {
return this.createQueryBuilder('user')
.where('user.isActive = :isActive', { isActive: true })
.getMany();
}
// Метод для поиска по email с проверкой существования
async findByEmailOrFail(email: string): Promise<User> {
const user = await this.findOne({ where: { email } });
if (!user) {
throw new Error(`User with email ${email} not found`);
}
return user;
}
}
- Использование в сервисе:
// user.service.ts import { UserRepository } from './user.repository';
class UserService { constructor(private userRepository: UserRepository) {}
async getActiveUsers() { // Используем кастомный метод репозитория return await this.userRepository.findActiveUsers(); }
async createUser(userData: Partial
**Преимущества использования репозиториев в Node.js:**
* **Тестируемость:** Легко подменить реальный репозиторий моком в unit-тестах.
* **Согласованность:** Все запросы к таблице `users` централизованы в одном классе.
* **Изоляция бизнес-логики:** Сервисы не зависят от конкретной ORM или способа построения запросов.
* **Повторное использование:** Сложные запросы, используемые в разных частях приложения, пишутся один раз.
В других ORM, таких как Prisma, паттерн репозитория часто реализуется вручную поверх сгенерированного клиента Prisma для достижения тех же целей абстракции и тестируемости.