Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Flutter REST API Example (flutter-rest-api)

Flutter Dart Material 3 Architecture State Management HTTP Client License: MIT

A production-ready, highly scalable Flutter REST API reference project demonstrating senior engineering patterns: Clean Architecture, SOLID Principles, Riverpod State Management, and Dio Networking with Material 3 Design.


πŸ“Œ Project Overview

This repository demonstrates how to architect a real-world enterprise Flutter application with robust networking capabilities:

  • Clean Architecture & Feature-First Directory Structure
  • Generic ApiClient Wrapper for GET, POST, PUT, PATCH, DELETE, Multipart Upload, and File Download
  • Dio Interceptors Stack: Logging, Authorization, Token Refresh with Request Locking, Retry with Exponential Backoff, and Domain Error Interceptors
  • JWT Token Lifecycle Management: Access token injection, auto-refresh on 401 Unauthorized, queueing concurrent requests, and secure local storage
  • Domain Exception Mapping: Converts network outages, timeouts, and status codes (400, 401, 403, 404, 409, 422, 500) into user-friendly UI error notifications
  • In-Memory Caching: TTL expiration strategy preventing unnecessary remote HTTP requests
  • Pagination Patterns: Infinite scrolling, Pull-to-Refresh, Load-More, and dual support for Page-Based and Cursor-Based pagination strategies
  • Material 3 UI: Shimmer loading skeletons, empty states, error retry widgets, and dynamic Light/Dark mode toggling

πŸ— Architecture & Flow Diagrams

High-Level Clean Architecture Layers

                               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                               β”‚     Presentation Layer      β”‚
                               β”‚  (Widgets, Screens, UI)    β”‚
                               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                              β”‚
                                              β–Ό
                               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                               β”‚   State Management Layer    β”‚
                               β”‚   (Riverpod StateNotifiers) β”‚
                               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                              β”‚
                                              β–Ό
                               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                               β”‚      Domain & Repository    β”‚
                               β”‚   (Interfaces, Entities)    β”‚
                               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                              β”‚
                                              β–Ό
                               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                               β”‚    Data & Network Layer     β”‚
                               β”‚ (Dio, ApiClient, Storage)   β”‚
                               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Network Interceptor Pipeline

sequenceDiagram
    autonumber
    actor UI as Presentation (Riverpod)
    participant AC as ApiClient
    participant AI as AuthInterceptor
    participant TRI as TokenRefreshInterceptor
    participant RI as RetryInterceptor
    participant EI as ErrorInterceptor
    participant API as Remote REST Server

    UI->>AC: Execute HTTP Request
    AC->>AI: Attach Authorization: Bearer Token
    AI->>TRI: Forward Request Options
    TRI->>RI: Forward Request
    RI->>API: Transmit over Network
    alt Successful Response (2xx)
        API-->>AC: Return JSON Response
        AC-->>UI: ApiResult.success(data)
    else 401 Unauthorized (Token Expired)
        API-->>TRI: 401 Unauthorized
        TRI->>TRI: Lock Request Queue & Execute Token Refresh API
        TRI->>API: Retry original request with new Access Token
        API-->>AC: Return JSON Response
    else Network / Transient Server Error (5xx)
        API-->>RI: Connection Timeout or 500
        RI->>RI: Exponential Backoff Delay & Retry
        RI->>API: Retry Request
    else Terminal API Error
        API-->>EI: 400 / 403 / 404 / 422 / 500
        EI->>AC: Wrap in Domain ApiException
        AC-->>UI: ApiResult.failure(userFriendlyMessage)
    end
Loading

πŸ“ Directory Structure

lib/
β”œβ”€β”€ main.dart                       # App entry point, Flutter binding & ProviderScope
β”œβ”€β”€ app.dart                        # Main shell, Material 3 Theme, Navigation shell
β”œβ”€β”€ core/                           # Cross-cutting core architecture modules
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”œβ”€β”€ env_config.dart         # Multi-environment config (Dev, Staging, Prod)
β”‚   β”‚   β”œβ”€β”€ app_constants.dart      # Storage keys, Endpoints, Headers, Pagination defaults
β”‚   β”‚   └── theme_config.dart       # Material 3 light & dark theme setup
β”‚   β”œβ”€β”€ network/
β”‚   β”‚   β”œβ”€β”€ api_client.dart         # Generic Dio HTTP API client wrapper
β”‚   β”‚   β”œβ”€β”€ api_response.dart       # ApiResponse<T>, PaginatedResponse<T>, ApiResult<T>
β”‚   β”‚   β”œβ”€β”€ api_exception.dart      # ApiException hierarchy & error message converters
β”‚   β”‚   β”œβ”€β”€ cache_manager.dart      # In-memory TTL response cache manager
β”‚   β”‚   └── interceptors/
β”‚   β”‚       β”œβ”€β”€ logging_interceptor.dart        # Formatted console logging
β”‚   β”‚       β”œβ”€β”€ auth_interceptor.dart           # Dynamic Bearer header injection
β”‚   β”‚       β”œβ”€β”€ token_refresh_interceptor.dart  # Thread-safe 401 token refresh handler
β”‚   β”‚       β”œβ”€β”€ error_interceptor.dart          # Dio to Domain ApiException converter
β”‚   β”‚       └── retry_interceptor.dart          # Exponential backoff retry handler
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ storage_service.dart     # Secure token & user session storage
β”‚   β”‚   β”œβ”€β”€ connectivity_service.dart# Real-time network status detector
β”‚   β”‚   └── download_service.dart    # Device downloads path generator
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”œβ”€β”€ user_model.dart          # User entity DTO & JSON converters
β”‚   β”‚   β”œβ”€β”€ auth_model.dart          # Auth tokens & Login payload models
β”‚   β”‚   └── pagination_model.dart    # Page & Cursor pagination parameters
β”‚   β”œβ”€β”€ repositories/
β”‚   β”‚   β”œβ”€β”€ auth_repository.dart     # Abstract interface & impl for Authentication
β”‚   β”‚   β”œβ”€β”€ user_repository.dart     # Abstract interface & impl for User CRUD
β”‚   β”‚   └── file_repository.dart     # Abstract interface & impl for Upload/Download
β”‚   └── providers/
β”‚       └── core_providers.dart      # Riverpod dependency injection registry
β”œβ”€β”€ features/                        # Feature-first modular components
β”‚   β”œβ”€β”€ auth/                        # Authentication feature
β”‚   β”‚   β”œβ”€β”€ presentation/login_screen.dart
β”‚   β”‚   └── providers/auth_provider.dart
β”‚   β”œβ”€β”€ users/                       # User management & directory
β”‚   β”‚   β”œβ”€β”€ presentation/
β”‚   β”‚   β”‚   β”œβ”€β”€ user_list_screen.dart
β”‚   β”‚   β”‚   β”œβ”€β”€ user_detail_screen.dart
β”‚   β”‚   β”‚   └── user_form_dialog.dart
β”‚   β”‚   └── providers/user_provider.dart
β”‚   β”œβ”€β”€ media/                       # File Upload & Download showcase
β”‚   β”‚   β”œβ”€β”€ presentation/
β”‚   β”‚   β”‚   β”œβ”€β”€ upload_demo_screen.dart
β”‚   β”‚   β”‚   └── download_demo_screen.dart
β”‚   β”‚   └── providers/file_provider.dart
β”‚   β”œβ”€β”€ pagination/                  # Pagination strategy showcase
β”‚   β”‚   └── presentation/pagination_demo_screen.dart
β”‚   └── theme/
β”‚       └── providers/theme_provider.dart
└── shared/                          # Reusable UI widgets & state views
    └── widgets/
        β”œβ”€β”€ skeleton_loader.dart     # Shimmer skeleton loaders
        β”œβ”€β”€ empty_view.dart          # Clean empty state widget
        β”œβ”€β”€ error_view.dart          # Error retry view widget
        β”œβ”€β”€ custom_button.dart       # Primary & Outlined action button with loading spinner
        └── custom_text_field.dart   # Styled M3 text field with validation

πŸ›  Packages & Dependencies

Package Purpose
flutter_riverpod Reactive state management & dependency injection
dio Powerful HTTP client with Interceptors, Form-data, and CancelTokens
flutter_secure_storage Encrypted storage for access & refresh JWT tokens
shared_preferences Key-value local storage for app settings & theme preference
shimmer Material 3 skeleton loading placeholders
connectivity_plus Real-time network connectivity checking
path_provider Cross-platform filesystem path resolution
mocktail Type-safe mocking library for unit testing

⚑ Getting Started

Prerequisites

  • Flutter SDK ^3.19.0 or later
  • Dart SDK ^3.3.0 or later

Installation

  1. Clone the repository:

    git clone https://github.com/your-username/flutter-rest-api.git
    cd flutter-rest-api
  2. Install pub packages:

    flutter pub get
  3. Run code analyzer:

    flutter analyze
  4. Execute unit tests:

    flutter test
  5. Launch Application:

    flutter run

πŸ’‘ Best Practices Implemented

  1. SOLID Principles:

    • Single Responsibility: Each class has one focused duty (e.g. AuthInterceptor only injects headers, UserListNotifier only manages list state).
    • Open/Closed: Repository interfaces (IUserRepository, IAuthRepository) allow extending implementations without mutating clients.
    • Liskov Substitution: Storage implementations are fully interchangeable.
    • Interface Segregation: Clean, unbloated contracts for repositories.
    • Dependency Inversion: High-level modules depend on abstractions via Riverpod providers.
  2. Robust Network Resilience:

    • Automatic retries with exponential backoff on transient network drops.
    • Seamless token refreshing without interrupting user interactions.
    • Graceful offline fallback messaging.
  3. Zero Secrets & Security:

    • Tokens stored in encrypted OS keychain / key store.
    • Base URLs isolated inside EnvConfig.
    • Zero hardcoded passwords or API keys.

πŸ›£ Future Improvements

  • Add OAuth2 Authorization Code flow support.
  • Implement GraphQL API client comparison module.
  • Add integration test suite with integration_test.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

About

Flutter application demonstrating REST API integration using clean architecture and best practices.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages