Skip to main content
Bitwarden Server uses the Repository pattern to abstract data access. Repositories provide a collection-like interface for accessing entities while hiding the underlying database implementation details.

Repository Architecture

Base Repository Interface

All repositories inherit from IRepository<T, TId>:
src/Core/Repositories/IRepository.cs

Standard Operations

  • GetByIdAsync - Retrieve entity by primary key
  • CreateAsync - Insert new entity, returns created entity with generated ID
  • ReplaceAsync - Update existing entity
  • UpsertAsync - Insert or update based on existence
  • DeleteAsync - Delete entity

Domain Repository Interfaces

Domain repositories extend the base interface with specific queries.

IUserRepository

src/Core/Repositories/IUserRepository.cs

IOrganizationRepository

ICipherRepository

Implementation: Dapper

The Dapper implementation uses stored procedures for all operations.

UserRepository Example

src/Infrastructure.Dapper/Repositories/UserRepository.cs

Key Dapper Patterns

Stored Procedure Calls:
Table-Valued Parameters:
Read-Only Replicas:

Implementation: Entity Framework

The EF Core implementation uses LINQ queries.

UserRepository Example

src/Infrastructure.EntityFramework/Repositories/UserRepository.cs

Key EF Patterns

LINQ Queries:
Database-Specific Logic:
AutoMapper Integration:

Stored Procedures (Dapper)

Naming Convention

Stored procedures follow the pattern: [TableName]_[Operation][Descriptor?] Examples:
  • User_ReadByEmail
  • User_ReadByGatewayCustomerId
  • User_Create
  • User_Update
  • User_DeleteById
  • OrganizationUser_ReadByOrganizationId
  • Cipher_SoftDelete

Common Stored Procedures

Read Operations:
  • [Table]_ReadById
  • [Table]_ReadBy[Column]
  • [Table]_ReadByUserId
  • [Table]_ReadByOrganizationId
Write Operations:
  • [Table]_Create
  • [Table]_Update
  • [Table]_DeleteById
Bulk Operations:
  • [Table]_CreateMany
  • [Table]_UpdateMany
  • [Table]_DeleteByIds

Repository Usage in Services

Repositories are injected into services via dependency injection:

Transactions

Dapper Transactions

Entity Framework Transactions

Choosing an Implementation

The repository implementation is configured in Startup.cs:
src/Api/Startup.cs

Performance Considerations

Connection Management

Query Optimization

Use read replicas for queries:
Paginate large result sets:
Use specific projections:

Testing Repositories

Unit Testing with Mocks

Integration Testing

See Also