Interface Repository<T, ID>

Generic repository interface for domain entities.

Following DDD principles, the only required method is save(). Repositories represent collections of domain entities, not data access objects.

Additional methods are optional and should be added to specific repository interfaces based on your use case requirements.

// Base usage - only save required
class UserRepository implements Repository<User, string> {
async save(user: User): Promise<void> {
const data = this.mapper.toPersistence(user);
await this.db.query('INSERT INTO users ... ON CONFLICT UPDATE ...', data);
}
}

// Extended interface for specific needs
interface UserRepository extends Repository<User, string> {
findById(id: string): Promise<User | null>; // Now required for this repo
findByEmail(email: string): Promise<User | null>;
}
interface Repository<T, ID = string> {
    save(entity: T): Promise<void>;
    findById(id: ID): Promise<null | T>;
    findAll(): Promise<T[]>;
    delete(id: ID): Promise<void>;
    exists(id: ID): Promise<boolean>;
}

Type Parameters

  • T

    The entity type

  • ID = string

    The entity ID type

Methods

  • Saves an entity (insert or update).

    This is the only required method following DDD principles. Repositories should act like collections where you add/update entities.

    Parameters

    • entity: T

      The entity to save

    Returns Promise<void>

    const user = User.create({ email: 'user@example.com', name: 'John' });
    await repository.save(user);
  • Finds an entity by its ID.

    Optional - implement if you need to retrieve entities by ID.

    Parameters

    • id: ID

      The entity ID

    Returns Promise<null | T>

    The entity if found, null otherwise

    const user = await repository.findById('user-123');
    if (user) {
    console.log(user.name);
    }
  • Finds all entities.

    Optional - use with caution in production systems with large datasets. Consider pagination or specific query methods instead.

    Returns Promise<T[]>

    An array of all entities

    const users = await repository.findAll();
    
  • Deletes an entity by its ID.

    Optional - consider soft deletes or event sourcing patterns instead. Hard deletes may not be appropriate for all use cases.

    Parameters

    • id: ID

      The entity ID

    Returns Promise<void>

    await repository.delete('user-123');
    
  • Checks if an entity exists by its ID.

    Optional - can often be implemented using findById instead.

    Parameters

    • id: ID

      The entity ID

    Returns Promise<boolean>

    true if the entity exists, false otherwise

    if (await repository.exists('user-123')) {
    console.log('User exists');
    }