Repository - Feelynx/flutter_clean_architecture GitHub Wiki
The Repository interface defines the contract for managing data interactions between the domain layer and data sources. In Clean Architecture, repositories act as the intermediary between the domain and data layers, consolidating and abstracting the complexities of data access (e.g., from remote APIs or local databases). Repositories return entities that represent the core business objects in the domain layer, ensuring that the application’s business logic remains decoupled from the details of data fetching.
- Data Abstraction: Repositories abstract data fetching and updating operations, whether the data comes from a remote source, a local database, or both.
- Entity Handling: They return entities to the domain layer and manage the transformation from DTOs (retrieved from data sources) into entities.
- Error Handling: Repositories typically include logic to handle errors, retries, and fallback strategies when interacting with data sources.
Example Interface: AuthRepository
The AuthRepository interface below defines methods for managing user session data and authentication within the application. The methods return ResponseWrapper objects, which encapsulate the response data and any potential errors.
abstract class AuthRepository {
Future<ResponseWrapper<UserSessionResponseEntity>> getUserSession(
UserSessionRequestEntity authRequestEntity,
);
Future<ResponseWrapper<RefreshUserSessionResponseEntity>> refreshUserSession(
RefreshUserSessionRequestEntity refreshTokenRequestEntity,
);
Future<ResponseWrapper<UserEntity>> getUser();
}
This interface ensures that the domain layer can retrieve authentication-related entities, without needing to know about the underlying data sources or how data is fetched or refreshed.
The RepositoryImpl class is a concrete implementation of the Repository interface. It interacts with one or more data sources (e.g., remote APIs, databases) to fetch or modify data. This class handles the transformation of data from Data Transfer Objects (DTOs) into entities and applies business logic as needed.
In this example, AuthRepositoryImpl implements the AuthRepository interface by interacting with the AuthRemoteDataSource to retrieve, refresh, and fetch user session and authentication details. The responses from the data source are converted from DTOs to entities before being returned to the domain layer.
This interface ensures that the domain layer can retrieve authentication-related entities, without needing to know about the underlying data sources or how data is fetched or refreshed.
class AuthRepositoryImpl implements AuthRepository {
final AuthRemoteDataSource _authRemoteDataSource;
AuthRepositoryImpl({required AuthRemoteDataSource authRemoteDataSource})
: _authRemoteDataSource = authRemoteDataSource;
@override
Future<ResponseWrapper<UserSessionResponseEntity>> getUserSession(
UserSessionRequestEntity authRequestEntity,
) {
return execute(() async {
final response = await _authRemoteDataSource.getUserSession(
authRequestEntity.toDTO(),
);
return response.toEntity();
});
}
@override
Future<ResponseWrapper<RefreshUserSessionResponseEntity>> refreshUserSession(
RefreshUserSessionRequestEntity refreshTokenRequestEntity,
) {
return execute(() async {
final response = await _authRemoteDataSource.refreshUserSession(
refreshTokenRequestEntity.toDTO(),
);
return response.toEntity();
});
}
@override
Future<ResponseWrapper<UserEntity>> getUser() {
return execute(() async {
final response = await _authRemoteDataSource.getUser();
return response.toEntity();
});
}
}
In this implementation:
- The AuthRepositoryImpl interacts with AuthRemoteDataSource to execute the operations defined in the interface.
- DTOs from the remote data source are mapped into entities before being returned to the domain.
- The execute function is used to handle common operations, such as error handling, and ensures that each request follows a consistent structure.
The Repository interface defines a contract for data interaction, hiding the details of data sources from the domain layer. The RepositoryImpl class implements this contract by handling the transformation of DTOs into entities, managing data interactions with external sources, and applying error-handling mechanisms. This pattern ensures that the domain layer is decoupled from data fetching logic, allowing for easier testing and maintenance in a Clean Architecture setup.