flutter_api_helper
Flutter के लिए एक शक्तिशाली, आसान उपयोग करने वाला API हेल्पर जो सरल GET अनुरोध से लेकर जटिल त्रुटि प्रबंधन, कैशिंग और टोकन प्रबंधन तक सभी कार्यों को हैंडल करता है।
ranahammad7/flutter_api_helper open-source repository details.
{"sdk":"flutter"}^1.1.0^2.2.2^5.0.1^1.9.1{"sdk":"flutter"}^3.0.0^5.4.2^2.4.7यह अंग्रेज़ी मूल स्नैपशॉट है। नवीनतम सामग्री GitHub पर देखें।
pub package License: MIT GitHub stars Flutter
Built-in caching • Smart retry logic • Seamless widget integration
|
✅ Simple API - Intuitive methods for all HTTP operations |
✅ Network Aware - Built-in connectivity checking |
| 🆚 Comparison | Built-in HTTP | Flutter API Helper |
|---|---|---|
| Setup | Complex boilerplate | ✨ One-line configuration |
| Caching | Manual implementation | 🧠 Smart auto-caching |
| Retries | Custom retry logic | 🔄 Exponential backoff |
| Errors | Generic exceptions | 🛡️ Typed error handling |
| Files | Complex multipart | 📁 Simple upload/download |
| Widgets | Custom FutureBuilder | 🎯 Ready ApiBuilder |
Add this to your package's pubspec.yaml file:
dependencies:
flutter_api_helper: ^1.0.0
Then run:
flutter pub get
import 'package:flutter_api_helper/flutter_api_helper.dart';
void main() {
// 🔧 Configure once, use everywhere
ApiHelper.configure(
ApiConfig(
baseUrl: 'https://api.yourapp.com',
enableLogging: true,
timeout: Duration(seconds: 30),
// 🧠 Smart caching out of the box
cacheConfig: CacheConfig(duration: Duration(minutes: 5)),
// 🔄 Auto-retry with exponential backoff
retryConfig: RetryConfig(maxRetries: 3),
),
);
runApp(MyApp());
}
// GET request with automatic type casting
final users = await ApiHelper.get<List<User>>('/users');
// POST request with smart error handling
final newUser = await ApiHelper.post('/users', data: {
'name': 'John Doe',
'email': 'john@example.com',
});
// PUT request with caching
final updatedUser = await ApiHelper.put('/users/1',
data: {'name': 'Jane Doe'},
cache: CacheConfig(duration: Duration(minutes: 10)),
);
// DELETE request with retry logic
await ApiHelper.delete('/users/1',
retry: RetryConfig(maxRetries: 5),
);
Transform your UI with the ApiBuilder widget:
class UsersList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ApiBuilder<List<User>>(
future: ApiHelper.get('/users'),
builder: (users) => ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
final user = users[index];
return ListTile(
leading: CircleAvatar(child: Text(user.name[0])),
title: Text(user.name),
subtitle: Text(user.email),
);
},
),
loading: Center(child: CircularProgressIndicator()),
error: (error) => ErrorWidget('Failed to load users: ${error.message}'),
empty: Center(child: Text('No users found')),
);
}
}
// 🧠 Cache response for 10 minutes
final posts = await ApiHelper.get(
'/posts',
cache: CacheConfig(duration: Duration(minutes: 10)),
);
// 🗑️ Clear cache when needed
await ApiHelper.clearCache();
await ApiHelper.clearCacheForUrl('/posts');
ApiHelper.configure(
ApiConfig(
baseUrl: 'https://api.yourapp.com',
// 🔑 Automatic token injection
getToken: () async => await TokenStorage.getToken(),
// 🔄 Automatic token refresh
onTokenExpired: () async => await AuthService.refreshToken(),
),
);
// 📤 Upload with real-time progress
final file = File('/path/to/image.jpg');
final response = await ApiHelper.uploadFile(
'/upload',
file,
fieldName: 'image',
fields: {'description': 'Profile picture'},
onProgress: (sent, total) {
final percentage = (sent / total * 100).round();
print('Upload Progress: $percentage%');
},
);
// 📥 Download with progress tracking
await ApiHelper.downloadFile(
'/files/document.pdf',
'/local/path/document.pdf',
onProgress: (received, total) {
final percentage = (received / total * 100).round();
print('Download Progress: $percentage%');
},
);
try {
final data = await ApiHelper.get('/api/data');
// Handle success
} catch (e) {
if (e is ApiError) {
switch (e.type) {
case ApiErrorType.network:
showSnackBar('Check your internet connection');
break;
case ApiErrorType.server:
showSnackBar('Server is temporarily unavailable');
break;
case ApiErrorType.timeout:
showSnackBar('Request timed out. Please try again');
break;
case ApiErrorType.authentication:
redirectToLogin();
break;
default:
showSnackBar('Something went wrong: ${e.message}');
}
}
}
final data = await ApiHelper.get(
'/unstable-endpoint',
retry: RetryConfig(
maxRetries: 5,
retryDelay: Duration(seconds: 2),
useExponentialBackoff: true, // 2s, 4s, 8s, 16s, 32s
maxRetryDelay: Duration(seconds: 30),
),
);
class AuthInterceptor extends ApiInterceptor {
@override
Future<void> onRequest(String method, String url,
Map<String, String>? headers, dynamic data) async {
headers?['Authorization'] = 'Bearer ${await getToken()}';
headers?['User-Agent'] = 'MyApp/1.0';
}
@override
Future<void> onResponse(http.Response response) async {
if (response.statusCode == 401) {
await refreshToken();
}
// Log analytics
Analytics.trackApiCall(response.request?.url.toString());
}
}
// Add the interceptor
ApiHelper.instance.addInterceptor(AuthInterceptor());
ApiConfig(
baseUrl: 'https://api.example.com', // 🌐 Base URL for all requests
defaultHeaders: {'Accept': 'application/json'}, // 📋 Default headers
timeout: Duration(seconds: 30), // ⏱️ Request timeout
enableLogging: true, // 📝 Enable request/response logging
getToken: () async => 'your-token', // 🔑 Token getter function
onTokenExpired: () async => refreshToken(), // 🔄 Token refresh callback
onError: (error) => handleError(error), // 🚨 Global error handler
retryConfig: RetryConfig(...), // 🔄 Default retry configuration
cacheConfig: CacheConfig(...), // 💾 Default cache configuration
)
CacheConfig(
duration: Duration(minutes: 5), // ⏰ How long to cache responses
keyPrefix: 'myapp_', // 🏷️ Prefix for cache keys
useMemoryCache: true, // 🧠 Enable in-memory cache
useDiskCache: true, // 💽 Enable persistent disk cache
maxCacheSize: 10 * 1024 * 1024, // 📏 Maximum cache size (10MB)
)
RetryConfig(
maxRetries: 3, // 🔢 Maximum retry attempts
retryDelay: Duration(seconds: 1), // ⏱️ Initial delay between retries
useExponentialBackoff: true, // 📈 Use exponential backoff strategy
maxRetryDelay: Duration(seconds: 30), // ⏰ Maximum delay between retries
retryStatusCodes: [408, 429, 500, 502, 503, 504], // 📋 HTTP status codes to retry
)
The package provides detailed error classification:
| Error Type | Description | Common Causes |
|---|---|---|
ApiErrorType.network |
Network connectivity issues | No internet, DNS issues |
ApiErrorType.timeout |
Request timeout errors | Slow connection, server overload |
ApiErrorType.server |
Server errors (5xx status codes) | Internal server error, maintenance |
ApiErrorType.client |
Client errors (4xx status codes) | Bad request, unauthorized |
ApiErrorType.authentication |
Authentication/authorization errors | Invalid token, expired session |
ApiErrorType.parsing |
JSON parsing errors | Malformed response, unexpected format |
ApiErrorType.unknown |
Unclassified errors | Unexpected exceptions |
The package is designed to be testable. You can easily mock API responses:
void main() {
group('API Tests', () {
test('should fetch users successfully', () async {
// Mock your API calls here
final users = await ApiHelper.get<List<User>>('/users');
expect(users, isA<List<User>>());
expect(users.isNotEmpty, true);
});
test('should handle network errors gracefully', () async {
expect(
() => ApiHelper.get('/invalid-endpoint'),
throwsA(isA<ApiError>()),
);
});
});
}
| Platform | Status | Notes |
|---|---|---|
| Android | ✅ | Full support |
| iOS | ✅ | Full support |
| Web | ✅ | Full support |
| macOS | ✅ | Full support |
| Windows | ✅ | Full support |
| Linux | ✅ | Full support |
>=3.0.0>=2.17.0For complete examples, check out the example folder which includes:
We welcome contributions! Please see our Contributing Guide for details.
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)See CHANGELOG.md for a detailed history of changes.
This project is licensed under the MIT License - see the LICENSE file for details.
If this package helped you, please consider giving it a ⭐ on GitHub!