flint_client 0.0.1+2
flint_client: ^0.0.1+2 copied to clipboard
A powerful, type-safe HTTP client for Dart with interceptors, caching, retries, and comprehensive error handling."
flint_client #
Official Dart client for the Flint framework.
Developed and maintained by Eulogia.
A powerful, feature-rich HTTP client for Dart and Flutter with built-in caching, retry mechanisms, interceptors, and customizable status code handling.
π Features #
- π Smart Retry Logic: Configurable retry with exponential backoff and jitter
- πΎ Built-in Caching: Memory cache with configurable TTL and freshness ratios
- π― Customizable Status Codes: Define your own success/error/redirect status mappings
- π File Upload/Download: Multipart form support with progress tracking
- π§ Interceptors: Request/response interceptors for authentication and logging
- β±οΈ Progress Tracking: Real-time upload/download progress callbacks
- π‘οΈ Type Safety: Generic response types with custom JSON parsers
- π Debug Logging: Comprehensive debug output for development
- π¦ Zero Dependencies: Pure Dart implementation
π¦ Installation #
Add this to your pubspec.yaml:
dependencies:
flint_client:
git:
url: https://github.com/flint-dart/flint-client.git
Then run:
dart pub get
π§ Quick Start #
Basic Usage #
import 'package:flint_client/flint_client.dart';
void main() async {
final client = FlintClient(
baseUrl: "https://api.example.com",
debug: true, // Enable debug logging
);
final response = await client.get<User>("/users/1",
parser: (json) => User.fromJson(json),
);
if (response.isSuccess) {
print("User: ${response.data}");
} else {
print("Error: ${response.error}");
}
client.dispose();
}
Advanced Configuration #
final client = FlintClient(
baseUrl: "https://api.example.com",
headers: {
'Authorization': 'Bearer your-token',
'Content-Type': 'application/json',
},
timeout: Duration(seconds: 30),
debug: true,
statusCodeConfig: StatusCodeConfig.custom(
successCodes: {200, 201, 204},
errorCodes: {400, 401, 403, 404, 422, 500},
redirectCodes: {301, 302},
),
onError: (error) {
print('Request failed: ${error.message}');
},
);
π Usage Examples #
GET Request with Caching #
final response = await client.get<List<Product>>(
'/products',
cacheConfig: CacheConfig(
maxAge: Duration(minutes: 10),
forceRefresh: false,
),
parser: (json) {
if (json is List) {
return json.map((item) => Product.fromJson(item)).toList();
}
return [];
},
);
POST Request with JSON Body #
final response = await client.post<Product>(
'/products',
body: {
'title': 'New Product',
'price': 29.99,
'category': 'electronics',
},
parser: (json) => Product.fromJson(json),
);
File Upload with Progress #
final response = await client.post<Map<String, dynamic>>(
'/upload',
files: {
'image': File('path/to/image.jpg'),
},
onSendProgress: (sent, total) {
final progress = (sent / total * 100).round();
print('Upload progress: $progress%');
},
);
Custom Status Code Handling #
// For APIs that use non-standard status codes
final customConfig = StatusCodeConfig.custom(
successCodes: {200, 201, 204, 304}, // Include 304 as success
errorCodes: {400, 401, 500}, // Only specific errors
redirectCodes: {302, 307},
);
final response = await client.get<User>(
'/user',
statusConfig: customConfig,
);
if (response.isSuccess) {
// Handle success according to your custom config
}
Error Handling with onDone Callback #
final response = await client.get<User>(
'/users/1',
onDone: (response, error) {
if (error != null) {
print('Request completed with error: ${error.message}');
} else {
print('Request completed successfully: ${response.statusCode}');
}
},
);
π API Reference #
HTTP Methods #
get<T>(path, {query, headers, cache, parser})post<T>(path, {body, files, headers, parser})put<T>(path, {body, files, headers, parser})patch<T>(path, {body, files, headers, parser})delete<T>(path, {headers, parser})
Configuration Options #
| Option | Type | Description |
|---|---|---|
baseUrl |
String |
Base URL for all requests |
headers |
Map<String, String> |
Default headers |
timeout |
Duration |
Request timeout duration |
debug |
bool |
Enable debug logging |
statusCodeConfig |
StatusCodeConfig |
Custom status code mappings |
onError |
ErrorHandler |
Global error callback |
onDone |
RequestDoneCallback |
Request completion callback |
Response Properties #
| Property | Type | Description |
|---|---|---|
statusCode |
int |
HTTP status code |
data |
T |
Response data (parsed) |
isSuccess |
bool |
Whether request succeeded |
isError |
bool |
Whether request failed |
isRedirect |
bool |
Whether response is redirect |
error |
FlintError |
Error object (if any) |
headers |
HttpHeaders |
Response headers |
duration |
Duration |
Request duration |
π οΈ Advanced Features #
Custom Interceptors #
final client = FlintClient(
baseUrl: 'https://api.example.com',
requestInterceptor: (request) async {
// Add auth token to all requests
request.headers.set('Authorization', 'Bearer $token');
},
responseInterceptor: (response) async {
// Log all responses
print('Response: ${response.statusCode}');
},
);
Retry Configuration #
final response = await client.get<User>(
'/users/1',
retryConfig: RetryConfig(
maxAttempts: 3,
delay: Duration(seconds: 1),
maxDelay: Duration(seconds: 10),
retryStatusCodes: {500, 502, 503},
),
);
Cache Management #
// Clear entire cache
await client.clearCache();
// Remove specific cached item
await client.removeCachedResponse('cache-key');
// Get cache size
final size = await client.cacheSize;
π― Status Code Configuration #
Handle non-standard APIs with custom status code mappings:
// For APIs that use 200 for errors
final weirdApiConfig = StatusCodeConfig.custom(
successCodes: {200}, // Only 200 is success
errorCodes: {200, 400, 500}, // 200 can be error!
redirectCodes: {302},
);
// Standard HTTP (default)
final standardConfig = StatusCodeConfig();
// Pre-defined configurations
final only200 = StatusCodeConfig.only200;
final broadSuccess = StatusCodeConfig.broadSuccess;
π Documentation #
- Full API Documentation
- GitHub Repository
- Issue Tracker
- Examples Folder - Complete usage examples
π€ Contributing #
We love contributions! Here's how to help:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
Development Setup #
git clone https://github.com/flint-dart/flint-client.git
cd flint-client
dart pub get
dart test
π License #
This project is licensed under the MIT License - see the LICENSE file for details.
ποΈ Built With #
π₯ Maintainers #
- Eulogia - Core maintainer
- Eulogia Website -
π Acknowledgments #
- Thanks to all our contributors and users
β Star this repo if you find it helpful!