CA
🚀 ApiClientPlus
🔥 Enterprise-Grade HTTP Client with Blazing Fast Performance
Intelligent caching • Multi-API management • Zero memory leaks
Quick Start • Features • Docs • Examples
🎯 Why ApiClientPlus?
⚡ Blazing Fast~12ms overhead |
🎨 Developer FriendlyClean API design |
🏢 Production ReadyExtensive testing |
✨ Features
🎯 Core Capabilities
✓ Multi-API Configuration // Manage multiple endpoints seamlessly
✓ Intelligent Caching // 6 strategies with auto-expiration
✓ Token Authentication // Auto-refresh & error handling
✓ Request Interceptors // Transform requests/responses
✓ Error Fallback // Graceful cache fallback
✓ Comprehensive Logging // Debug with precision🔄 Cache Strategies
| Strategy | Behavior | Best For |
|---|---|---|
| 🎯 cacheFirst | Cache → Network | General purpose APIs |
| 🌐 networkFirst | Network → Cache | Fresh data priority |
| 💾 cacheOnly | Cache exclusive | Offline-first apps |
| 🔴 networkOnly | No caching | Real-time updates |
| ⚡ staleWhileRevalidate | Instant + refresh | Performance critical |
| 🔄 cacheThenNetwork | Cache + background | Progressive loading |
📦 Installation
Add to your pubspec.yaml:
dependencies:
api_client_plus: ^1.0.0Install:
flutter pub get🚀 Quick Start
1️⃣ Initialize (One-Time Setup)
import 'package:api_client_plus/api_client_plus.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await ApiClientPlus().initialize(
configs: [
ApiConfig(
name: 'dev',
baseUrl: 'https://api.dev.example.com',
requiresAuth: true,
),
ApiConfig(
name: 'api',
baseUrl: 'https://api.example.com',
requiresAuth: true,
),
ApiConfig(
name: 'auth',
baseUrl: 'https://api.example.com',
requiresAuth: false,
),
],
defaultDomain: kReleaseMode ? 'prod' : 'dev',
cacheConfig: CacheConfig(
enableCache: true,
defaultTtl: Duration(minutes: 10),
),
logConfig: LogConfig(
showLog: kReleaseMode,
showCacheLog: false,
messageLimit: 300,
prettyJson: false,
isColored: true,
showCaller: false,
logStyle: LogStyle.minimal,
logLevel: "DEBUG",
),
tokenGetter: () async {
// final prefs = await SharedPreferences.getInstance();
// return prefs.getString('access_token');
return 'my_access_token';
},
onTokenInvalid: () async {
// Redirect logic here
},
onRequest: (options) async {
options.headers['User-Agent'] = 'MyApp/1.0.0';
},
onResponse: (response) async {
debugPrint('✅ ${response.statusCode} ${response.requestOptions.path}');
},
onError: (error) async {
debugPrint('❌ API Error: ${error.message}');
},
);
runApp(MyApp());
}2️⃣ Make API Calls
// Simple GET request with caching
final response = await ApiClientService.get(
'/users',
useCache: true,
cacheStrategy: ApiClientCacheStrategy.cacheFirst,
);
// POST with authentication
final user = await ApiClientService.post(
'/users',
data: {'name': 'John Doe', 'email': 'john@example.com'},
);
// PUT/PATCH updates
await ApiClientService.put('/users/123', data: updatedData);
await ApiClientService.patch('/users/123', data: partialData);
// DELETE
await ApiClientService.delete('/users/123');3️⃣ Handle Responses
try {
final response = await ApiClientService.get('/profile');
if (response.statusCode == 200) {
final user = response.data;
print('Welcome ${user['name']}!');
}
} on DioException catch (e) {
if (e.response?.statusCode == 401) {
// Token expired - auto-refresh triggered
} else if (e.type == DioExceptionType.connectionError) {
// Network error - cache fallback available
final cached = await ApiClientService.get(
'/profile',
cacheStrategy: ApiClientCacheStrategy.cacheOnly,
);
}
}🎨 Advanced Usage
🔐 Multi-API Configuration
Manage different API environments effortlessly:
await ApiClientPlus().initialize(
configs: [
ApiConfig(
name: 'auth',
baseUrl: 'https://auth.company.com',
requiresAuth: true,
connectTimeout: Duration(seconds: 30),
),
ApiConfig(
name: 'public',
baseUrl: 'https://api.company.com',
requiresAuth: false,
verboseLogging: false,
),
ApiConfig(
name: 'cdn',
baseUrl: 'https://cdn.company.com',
requiresAuth: false,
),
],
defaultDomain: 'auth',
);
// Switch between APIs seamlessly
final profile = await ApiClientService.get('/me', domainName: 'auth');
final posts = await ApiClientService.get('/posts', domainName: 'public');
final image = await ApiClientService.get('/avatar.png', domainName: 'cdn');⚡ Cache Optimization
// Stale-While-Revalidate: Instant response + background refresh
final data = await ApiClientService.get(
'/dashboard',
cacheStrategy: ApiClientCacheStrategy.staleWhileRevalidate,
useCache: true,
maxStale: Duration(hours: 1),
);
// Cache-Then-Network: Progressive enhancement
final products = await ApiClientService.get(
'/products',
cacheStrategy: ApiClientCacheStrategy.cacheThenNetwork,
onCachedResponse: (cached) {
// Show cached data immediately
updateUI(cached.data);
},
);🔒 Authentication Flow
await ApiClientPlus().initialize(
configs: [...],
tokenGetter: () async {
// Retrieve token from secure storage
return await SecureStorage.read('auth_token');
},
onTokenInvalid: () async {
// Handle expired tokens
await SecureStorage.delete('auth_token');
Navigator.pushReplacementNamed(context, '/login');
},
);🎯 Custom Headers & Options
final response = await ApiClientService.get(
'/data',
headers: {
'X-Custom-Header': 'value',
'X-Request-ID': uuid.v4(),
},
query: {
'page': 1,
'limit': 20,
'sort': 'desc',
},
timeout: Duration(seconds: 60),
);📊 Performance Benchmarks
Real-World Results
╔═══════════════════════════════════════════════════════════╗
║ Operation │ Time │ Rating ║
╠═══════════════════════════════════════════════════════════╣
║ API Call Overhead │ ~12ms │ ✅ Excellent ║
║ Route Matching │ ~600μs │ 🚀 Blazing Fast ║
║ Cache Retrieval │ ~2ms │ ⚡ Instant ║
║ Plugin Initialization │ ~13ms │ 🏎️ Quick ║
║ Memory Leaks │ 0 growth │ 🛡️ Rock Solid ║
╚═══════════════════════════════════════════════════════════╝
Cache Performance Impact
// 🌐 First Request (Network)
📥 Response Time: 450ms | Status: 200 | from_cache: false
// ⚡ Second Request (Cache)
📥 Response Time: 2ms | Status: 200 | from_cache: true
// 🎉 Result: 225x FASTER!Load Testing
✓ 100 sequential calls: 1.1 seconds (11ms avg)
✓ 50 domain switches: 549ms (10.98ms avg)
✓ 1000 route matches: 627ms (0.6ms avg)
✓ 10 client instances: 0ms (instant)
✓ 20 configs setup: 1ms (blazing)
🔧 Configuration Reference
ApiConfig
ApiConfig(
name: 'myapi', // Unique identifier
baseUrl: 'https://api.example.com',
connectTimeout: Duration(seconds: 30),
receiveTimeout: Duration(seconds: 30),
sendTimeout: Duration(seconds: 30),
requiresAuth: true, // Requires token
verboseLogging: false, // Detailed logs
maxRetries: 3, // Retry failed requests
defaultHeaders: { // Custom headers
'Accept': 'application/json',
'X-App-Version': '1.0.0',
},
extra: {'priority': 'high'}, // Custom metadata
)CacheConfig
CacheConfig(
enableCache: true,
defaultTtl: Duration(minutes: 15),
priority: CachePriority.normal,
hitCacheOnNetworkFailure: true, // Fallback on error
hitCacheOnErrorCodes: [500, 502, 503, 401, 403],
)LogConfig
LogConfig(
showLog: true,
showCacheLog: true,
logLevel: "DEBUG", // TRACE, DEBUG, INFO, WARN, ERROR
prettyJson: true,
isColored: true,
messageLimit: 300,
showTime: true,
showCaller: false,
logStyle: LogStyle.minimal, // minimal, standard, none
)🐛 Debugging
Enable Comprehensive Logging
await ApiClientPlus().initialize(
configs: [...],
logConfig: LogConfig(
showLog: true,
showCacheLog: true,
logLevel: "DEBUG",
prettyJson: true,
isColored: true,
),
);Sample Log Output
INFO 💾 Cache Strategy: cache_first for /users
INFO 💾 ✅ CACHE HIT: /users (age: 2m 34s)
INFO 📥 Response: 2ms | 200 | from_cache: true
INFO 🌐 Cache Strategy: network_first for /posts
INFO 🌐 Making network request...
INFO 📥 Response: 156ms | 200 | from_cache: false
INFO 💾 ✅ Cached: /posts (ttl: 10m)
Screenshots
🤝 Contributing
We welcome contributions! Here's how:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🆘 Support & Resources
| 📖 Documentation |
🐛 Report Bug |
💡 Request Feature |
⭐ Star on GitHub |
On this page
Languages
Dart98.7%HTML0.8%Swift0.4%Kotlin0.1%Objective-C0.0%
Contributors
MIT License
Created November 28, 2025
Updated November 30, 2025

