418 lines
27 KiB
Markdown
418 lines
27 KiB
Markdown
# API Integration Architecture
|
|
|
|
## Complete Data Flow Diagram
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ PRESENTATION LAYER │
|
|
│ │
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ ProductsPage │ │ CategoriesPage│ │ HomePage │ │
|
|
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
|
|
│ │ │ │ │
|
|
│ └──────────────────┴──────────────────┘ │
|
|
│ │ │
|
|
└────────────────────────────┼────────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ RIVERPOD PROVIDERS │
|
|
│ │
|
|
│ ┌─────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
|
|
│ │ProductsProvider │ │CategoriesProvider│ │ NetworkProvider │ │
|
|
│ └────────┬────────┘ └────────┬─────────┘ └────────┬─────────┘ │
|
|
│ │ │ │ │
|
|
└───────────┼─────────────────────┼─────────────────────┼────────────┘
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ USE CASES (Domain) │
|
|
│ │
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │GetAllProducts│ │GetCategories │ │SearchProducts│ │
|
|
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
|
|
│ │ │ │ │
|
|
└─────────┼──────────────────┼──────────────────┼────────────────────┘
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ REPOSITORIES (Data) │
|
|
│ │
|
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
|
│ │ ProductRepositoryImpl │ │
|
|
│ │ │ │
|
|
│ │ - Offline-first logic │ │
|
|
│ │ - Exception → Failure conversion │ │
|
|
│ │ - Cache + Remote coordination │ │
|
|
│ └──────────────────────┬──────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌───────────────┴───────────────┐ │
|
|
│ ▼ ▼ │
|
|
│ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ Local Source │ │ Remote Source│ │
|
|
│ │ (Hive) │ │ (API) │ │
|
|
│ └──────────────┘ └──────┬───────┘ │
|
|
└─────────────────────────────────────────┼──────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ NETWORK LAYER (Core) │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────┐ │
|
|
│ │ DIO CLIENT │ │
|
|
│ │ │ │
|
|
│ │ ┌────────────────────────────────────────────────────────┐ │ │
|
|
│ │ │ INTERCEPTORS │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ 1. Logging Interceptor │ │ │
|
|
│ │ │ → Log requests/responses │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ 2. Auth Interceptor │ │ │
|
|
│ │ │ → Add auth headers │ │ │
|
|
│ │ │ → Handle 401 errors │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ 3. Error Interceptor │ │ │
|
|
│ │ │ → Map status codes to exceptions │ │ │
|
|
│ │ │ → Extract error messages │ │ │
|
|
│ │ │ │ │ │
|
|
│ │ │ 4. Retry Interceptor │ │ │
|
|
│ │ │ → Retry on timeout/connection errors │ │ │
|
|
│ │ │ → Exponential backoff │ │ │
|
|
│ │ └────────────────────────────────────────────────────────┘ │ │
|
|
│ │ │ │
|
|
│ │ HTTP Methods: GET, POST, PUT, DELETE, PATCH │ │
|
|
│ └──────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────────┐ │
|
|
│ │ NETWORK INFO │ │
|
|
│ │ │ │
|
|
│ │ - Check connectivity status │ │
|
|
│ │ - Monitor connectivity changes │ │
|
|
│ │ - Detect connection type (WiFi/Mobile) │ │
|
|
│ └──────────────────────────────────────────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ BACKEND API │
|
|
│ │
|
|
│ GET /api/v1/products │
|
|
│ GET /api/v1/products/:id │
|
|
│ GET /api/v1/products/category/:categoryId │
|
|
│ GET /api/v1/products/search?q=query │
|
|
│ POST /api/v1/products/sync │
|
|
│ │
|
|
│ GET /api/v1/categories │
|
|
│ GET /api/v1/categories/:id │
|
|
│ POST /api/v1/categories/sync │
|
|
└─────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Error Handling Flow
|
|
|
|
```
|
|
┌──────────────┐
|
|
│ API Request │
|
|
└──────┬───────┘
|
|
│
|
|
▼
|
|
┌──────────────────┐
|
|
│ Network Check │
|
|
│ (NetworkInfo) │
|
|
└──────┬───────────┘
|
|
│
|
|
├─── No Connection ────────────────────────┐
|
|
│ │
|
|
▼ ▼
|
|
┌──────────────────┐ ┌────────────────────┐
|
|
│ Send Request │ │ NoInternetException│
|
|
│ via DioClient │ └────────────────────┘
|
|
└──────┬───────────┘ │
|
|
│ │
|
|
├─── Timeout ──────────────────────────────┤
|
|
│ │
|
|
├─── Connection Error ─────────────────────┤
|
|
│ │
|
|
▼ ▼
|
|
┌──────────────────┐ ┌────────────────────┐
|
|
│ Retry Interceptor│───── Max retries ──│ TimeoutException │
|
|
│ (3 attempts) │ reached │ ConnectionException│
|
|
└──────┬───────────┘ └────────────────────┘
|
|
│ │
|
|
│ Success after retry │
|
|
▼ ▼
|
|
┌──────────────────┐ ┌────────────────────┐
|
|
│ Error Interceptor│ │ Repository │
|
|
│ (Status codes) │ │ Converts to │
|
|
└──────┬───────────┘ │ Failure │
|
|
│ └────────────────────┘
|
|
│ │
|
|
├─── 400 ──────── BadRequestException │
|
|
├─── 401 ──────── UnauthorizedException │
|
|
├─── 403 ──────── ForbiddenException │
|
|
├─── 404 ──────── NotFoundException │
|
|
├─── 422 ──────── ValidationException │
|
|
├─── 429 ──────── RateLimitException │
|
|
├─── 500+ ─────── ServerException │
|
|
│ │
|
|
▼ ▼
|
|
┌──────────────────┐ ┌────────────────────┐
|
|
│ Success Response │ │ UI Layer │
|
|
│ Parse JSON │ │ Shows Error │
|
|
│ Return Model │ │ Message │
|
|
└──────────────────┘ └────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Authentication Flow
|
|
|
|
```
|
|
┌─────────────────┐
|
|
│ User Login │
|
|
└────────┬────────┘
|
|
│
|
|
▼
|
|
┌─────────────────┐
|
|
│ Auth API Call │
|
|
│ POST /login │
|
|
└────────┬────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────┐
|
|
│ Receive JWT Token │
|
|
│ { token: "...", │
|
|
│ refreshToken: "..." }│
|
|
└────────┬────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────┐
|
|
│ AuthInterceptor │
|
|
│ .setAuthToken(token) │
|
|
└────────┬────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────┐
|
|
│ All subsequent requests │
|
|
│ include: │
|
|
│ Authorization: │
|
|
│ Bearer <token> │
|
|
└────────┬────────────────┘
|
|
│
|
|
│
|
|
├──── Token Valid ────────► Continue Request
|
|
│
|
|
├──── 401 Unauthorized ───┐
|
|
│ │
|
|
▼ ▼
|
|
┌─────────────────────────┐ ┌────────────────────┐
|
|
│ AuthInterceptor detects │ │ Refresh Token │
|
|
│ 401 response │ │ POST /refresh │
|
|
└────────┬────────────────┘ └────────┬───────────┘
|
|
│ │
|
|
│ ▼
|
|
│ ┌────────────────────┐
|
|
│ │ Get New Token │
|
|
│ └────────┬───────────┘
|
|
│ │
|
|
│ ▼
|
|
│ ┌────────────────────┐
|
|
│ │ Update Token │
|
|
│ │ Retry Request │
|
|
│ └────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────┐
|
|
│ Refresh Failed? │
|
|
│ Clear token │
|
|
│ Navigate to Login │
|
|
└─────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Data Synchronization Flow
|
|
|
|
```
|
|
┌────────────────┐
|
|
│ App Launch │
|
|
└───────┬────────┘
|
|
│
|
|
▼
|
|
┌────────────────────────┐
|
|
│ Load from Hive Cache │
|
|
│ (Instant UI) │
|
|
└───────┬────────────────┘
|
|
│
|
|
▼
|
|
┌────────────────────────┐
|
|
│ Check Network Status │
|
|
└───────┬────────────────┘
|
|
│
|
|
├─── Offline ──────────────────────┐
|
|
│ │
|
|
▼ ▼
|
|
┌────────────────────────┐ ┌──────────────────┐
|
|
│ Fetch from API │ │ Use Cached Data │
|
|
│ (Background) │ │ Show Offline UI │
|
|
└───────┬────────────────┘ └──────────────────┘
|
|
│
|
|
▼
|
|
┌────────────────────────┐
|
|
│ Compare with Cache │
|
|
│ (by timestamp) │
|
|
└───────┬────────────────┘
|
|
│
|
|
├─── New Data Available ──┐
|
|
│ │
|
|
▼ ▼
|
|
┌────────────────────────┐ ┌──────────────────────┐
|
|
│ Update Hive Cache │ │ No Changes │
|
|
└───────┬────────────────┘ │ Keep Current Data │
|
|
│ └──────────────────────┘
|
|
▼
|
|
┌────────────────────────┐
|
|
│ Notify UI │
|
|
│ (Riverpod ref.refresh) │
|
|
└───────┬────────────────┘
|
|
│
|
|
▼
|
|
┌────────────────────────┐
|
|
│ UI Updates │
|
|
│ Show Fresh Data │
|
|
└────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Component Dependencies
|
|
|
|
```
|
|
┌──────────────────────────────────────────────┐
|
|
│ GetIt Service Locator │
|
|
│ │
|
|
│ ┌────────────────────────────────────────┐ │
|
|
│ │ Connectivity (External) │ │
|
|
│ └────────────┬───────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌────────────────────────────────────────┐ │
|
|
│ │ NetworkInfo │ │
|
|
│ │ - NetworkInfoImpl(Connectivity) │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌────────────────────────────────────────┐ │
|
|
│ │ DioClient │ │
|
|
│ │ - Dio instance │ │
|
|
│ │ - Interceptors │ │
|
|
│ └────────────┬───────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌────────────────────────────────────────┐ │
|
|
│ │ ProductRemoteDataSource │ │
|
|
│ │ - ProductRemoteDataSourceImpl(Dio) │ │
|
|
│ │ OR │ │
|
|
│ │ - ProductRemoteDataSourceMock() │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌────────────────────────────────────────┐ │
|
|
│ │ CategoryRemoteDataSource │ │
|
|
│ │ - CategoryRemoteDataSourceImpl(Dio) │ │
|
|
│ │ OR │ │
|
|
│ │ - CategoryRemoteDataSourceMock() │ │
|
|
│ └────────────────────────────────────────┘ │
|
|
│ │
|
|
│ (Future: Repositories, UseCases) │
|
|
└──────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## File Dependencies Graph
|
|
|
|
```
|
|
main.dart
|
|
│
|
|
├─► injection_container.dart
|
|
│ │
|
|
│ ├─► dio_client.dart
|
|
│ │ │
|
|
│ │ └─► api_interceptor.dart
|
|
│ │ │
|
|
│ │ └─► api_constants.dart
|
|
│ │ └─► exceptions.dart
|
|
│ │
|
|
│ ├─► network_info.dart
|
|
│ │ │
|
|
│ │ └─► connectivity_plus
|
|
│ │
|
|
│ ├─► product_remote_datasource.dart
|
|
│ │ │
|
|
│ │ ├─► dio_client.dart
|
|
│ │ ├─► product_model.dart
|
|
│ │ ├─► api_constants.dart
|
|
│ │ └─► exceptions.dart
|
|
│ │
|
|
│ └─► category_remote_datasource.dart
|
|
│ │
|
|
│ ├─► dio_client.dart
|
|
│ ├─► category_model.dart
|
|
│ ├─► api_constants.dart
|
|
│ └─► exceptions.dart
|
|
│
|
|
└─► app.dart (Riverpod providers)
|
|
```
|
|
|
|
---
|
|
|
|
## Testing Strategy
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ TESTING PYRAMID │
|
|
│ │
|
|
│ ┌───────┐ │
|
|
│ │ E2E │ │
|
|
│ │ Tests │ │
|
|
│ └───┬───┘ │
|
|
│ │ │
|
|
│ ┌───────┴───────┐ │
|
|
│ │ Integration │ │
|
|
│ │ Tests │ │
|
|
│ └───────┬───────┘ │
|
|
│ │ │
|
|
│ ┌───────────┴───────────┐ │
|
|
│ │ Widget Tests │ │
|
|
│ │ (with mock providers)│ │
|
|
│ └───────────┬───────────┘ │
|
|
│ │ │
|
|
│ ┌───────────────┴───────────────┐ │
|
|
│ │ Unit Tests │ │
|
|
│ │ - Data Sources (Mock/Real) │ │
|
|
│ │ - Network Info │ │
|
|
│ │ - DioClient │ │
|
|
│ │ - Interceptors │ │
|
|
│ │ - Exception Handling │ │
|
|
│ └───────────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────┘
|
|
|
|
Test Coverage Goals:
|
|
- Unit Tests: 80%+
|
|
- Widget Tests: 60%+
|
|
- Integration Tests: Key flows
|
|
- E2E Tests: Critical paths
|
|
```
|
|
|
|
---
|
|
|
|
**Architecture Status**: ✅ Complete
|
|
|
|
This architecture provides:
|
|
- Clean separation of concerns
|
|
- Offline-first capability
|
|
- Robust error handling
|
|
- Easy testing and mocking
|
|
- Scalable and maintainable structure
|