Question #282EasyFlutter BasicsImportant

what is the use of entity in flutter difference between using entity and models ?

#flutter

Answer

Entity vs Model in Flutter

In Clean Architecture, Entity and Model look similar but serve completely different purposes and live in different layers of your app.


What is an Entity?

An Entity is a pure Dart class that represents your business/domain object. It has no knowledge of JSON, APIs, databases, or any external framework.

dart
// domain/entities/user_entity.dart
class UserEntity {
  final String id;
  final String name;
  final String email;
  final bool isActive;

  UserEntity({
    required this.id,
    required this.name,
    required this.email,
    required this.isActive,
  });
}

Key traits:

  • Pure Dart — no imports from packages
  • No
    text
    fromJson()
    /
    text
    toJson()
    methods
  • Immutable
  • Contains business rules (e.g., validation logic)

What is a Model?

A Model is a data layer class that knows how to convert data from/to external sources (API JSON, database maps, SharedPreferences, etc.).

dart
// data/models/user_model.dart
class UserModel extends UserEntity {
  UserModel({
    required super.id,
    required super.name,
    required super.email,
    required super.isActive,
  });

  // Convert FROM JSON (API response)
  factory UserModel.fromJson(Map<String, dynamic> json) {
    return UserModel(
      id: json['user_id'],        // API field name mapping
      name: json['full_name'],    // Different key than entity field
      email: json['email_address'],
      isActive: json['is_active'] ?? true,
    );
  }

  // Convert TO JSON (API request)
  Map<String, dynamic> toJson() => {
    'user_id': id,
    'full_name': name,
    'email_address': email,
    'is_active': isActive,
  };
}

Key traits:

  • Lives in data layer
  • Has
    text
    fromJson()
    /
    text
    toJson()
    methods
  • Handles API field name mapping (e.g.,
    text
    user_id
    text
    id
    )
  • Extends or maps to the Entity

Where to Use Entity vs Model

This is the most important part — knowing which layer calls which:

text
┌─────────────────────────────────────────────────┐
│  PRESENTATION LAYER (UI)                        │
│  Screens, Widgets, Providers/BLoC               │
│  ✅ Uses: Entity                                │
│  ❌ Never touches: Model                        │
├─────────────────────────────────────────────────┤
│  DOMAIN LAYER (Business Logic)                  │
│  UseCases, Repository Interface                 │
│  ✅ Uses: Entity                                │
│  ❌ Never touches: Model                        │
├─────────────────────────────────────────────────┤
│  DATA LAYER (API/Database)                      │
│  Repository Impl, DataSources                   │
│  ✅ Uses: Model (for JSON/DB conversion)        │
│  ✅ Converts Model → Entity before returning    │
└─────────────────────────────────────────────────┘

Where to Call Model

Only in the Data Layer — inside DataSources and Repository Implementation:

dart
// data/datasources/user_remote_datasource.dart
class UserRemoteDataSource {
  final Dio dio;
  UserRemoteDataSource(this.dio);

  Future<UserModel> getUser(String id) async {
    final response = await dio.get('/users/$id');
    return UserModel.fromJson(response.data);  // ✅ Model used here
  }
}

// data/repositories/user_repository_impl.dart
class UserRepositoryImpl implements UserRepository {
  final UserRemoteDataSource remoteDataSource;
  UserRepositoryImpl(this.remoteDataSource);

  
  Future<UserEntity> getUser(String id) async {
    final UserModel model = await remoteDataSource.getUser(id);
    return model;  // ✅ Model extends Entity, so it IS an Entity
    // The rest of the app only sees UserEntity
  }
}

Where to Call Entity

In Domain and Presentation Layers — UseCases, Providers/BLoC, Screens:

dart
// domain/usecases/get_user_usecase.dart
class GetUserUseCase {
  final UserRepository repository;  // Abstract — no Model knowledge
  GetUserUseCase(this.repository);

  Future<UserEntity> call(String id) {  // ✅ Returns Entity
    return repository.getUser(id);
  }
}

// presentation/providers/user_provider.dart
class UserNotifier extends AsyncNotifier<UserEntity> {  // ✅ Entity
  
  Future<UserEntity> build() async {
    return ref.read(getUserUseCaseProvider).call('123');
  }
}

// presentation/screens/user_screen.dart
class UserScreen extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final UserEntity user = ref.watch(userProvider).value!;  // ✅ Entity
    return Text(user.name);  // UI only knows Entity fields
  }
}

Complete Data Flow

dart
// 1. API returns JSON
{"user_id": "123", "full_name": "John", "email_address": "john@email.com"}

// 2. DataSource converts JSON → Model (DATA LAYER)
UserModel model = UserModel.fromJson(json);

// 3. Repository returns Model as Entity (BOUNDARY)
UserEntity entity = model;  // Model extends Entity

// 4. UseCase receives Entity (DOMAIN LAYER)
final user = await getUserUseCase.call('123');

// 5. UI displays Entity fields (PRESENTATION LAYER)
Text(user.name);  // "John"

Why Separate Them?

Imagine your API changes

text
full_name
to
text
display_name
:

dart
// ✅ Only update the Model — nothing else changes
factory UserModel.fromJson(Map<String, dynamic> json) {
  return UserModel(
    name: json['display_name'],  // Changed only here
    // ...
  );
}

// Entity, UseCase, Provider, Screen — ZERO changes needed

Without separation, you'd update JSON parsing logic scattered across your entire app.


Comparison Table

AspectEntityModel
LayerDomain (business logic)Data (API/DB)
PurposeRepresent business objectSerialize/deserialize data
DependenciesNone (pure Dart)JSON, DB, API packages
Has fromJson/toJsonNoYes
Used in UIYesNo
Used in UseCasesYesNo
Used in DataSourcesNoYes
Used in RepositoryReturns EntityReceives Model, converts to Entity

Rule of Thumb: If you're writing

text
fromJson()
or
text
toJson()
— you need a Model. If you're passing data to a UseCase, Provider, or Widget — you need an Entity. The Repository is the boundary where Model converts to Entity.