arch-atlas

Create local data source and add hive

Data Layer

06:57

Summary

This lesson focuses on setting up the local data source for the Home feature in a Clean Architecture Flutter app. The instructor creates the abstract contract and implementation for HomeLocalDataSource, notably changing the return types from asynchronous Futures to synchronous lists, assuming instant access from a local cache. The lesson then transitions to choosing a local caching solution, selecting the Hive NoSQL package over SQLite due to its speed and simplicity for non-relational API responses, and concludes by installing the necessary Hive and code-generation dependencies.

Key Ideas

  • HomeLocalDataSource abstract class defines the contract for fetching cached BookEntity data.
  • Return types for local data fetching are set to synchronous List<BookEntity> rather than Future<List<BookEntity>> to reflect instant cache access.
  • Small, atomic Git commits are recommended to make discarding erroneous changes safer and easier.
  • Hive is selected over SQL (SQLite) because the data is fetched directly from an API and lacks complex relational requirements.
  • hive and hive_flutter are added as standard dependencies for database operations.
  • hive_generator and build_runner are strictly added as dev_dependencies to handle TypeAdapter code generation without bloating the production app.

Code Snippets

home_local_data_source.dart final statedart
import '../../domain/entities/book_entity.dart';

abstract class HomeLocalDataSource {
  List<BookEntity> fetchFeaturedBooks();
  List<BookEntity> fetchNewestBooks();
}

class HomeLocalDataSourceImpl extends HomeLocalDataSource {
  @override
  List<BookEntity> fetchFeaturedBooks() {
    // TODO: implement fetchFeaturedBooks
    throw UnimplementedError();
  }

  @override
  List<BookEntity> fetchNewestBooks() {
    // TODO: implement fetchNewestBooks
    throw UnimplementedError();
  }
}
Additions to pubspec.yaml (using Pubspec Assist extension)dart
dependencies:
  # ... other dependencies
  hive: ^2.2.3
  hive_flutter: ^1.1.0

dev_dependencies:
  # ... other dev dependencies
  hive_generator: ^2.0.0
  build_runner: ^2.3.3

Architecture Insight

Architecture insight

Hive is a fast key-value store, but it's an implementation detail. The local data source's contract is "give me the cached featured books" — Hive, SQLite, or a JSON file behind the scenes shouldn't matter to anyone above.

Generated TypeAdapters are a Hive-specific concept. Keeping them next to the model (in data/) preserves the rule: the domain layer never imports hive or any persistence package.

My Notes

The instructor makes a deliberate choice to drop Future from the local data source method signatures. This is a crucial architectural decision: it dictates that the chosen local storage must support synchronous reads. Hive supports this beautifully via box.get(), which reads directly from an in-memory map once the box is opened. [Editor's note] Be careful with this approach if you ever plan to swap Hive for SQLite/sqflite or Isar in the future, as those libraries strictly rely on asynchronous I/O (Future). By making the data source contract synchronous, you tightly couple your LocalDataSource abstraction to Hive's specific in-memory architecture. Additionally, the instructor's point on small, frequent Git commits is an excellent real-world software engineering practice. Keeping commits tightly scoped to single features or dependency additions prevents massive headaches when using git restore or discarding changes later.