सार्वजनिक जानकारी से बना चयन मार्गदर्शन। केवल संदर्भ हेतु।
एक फ्लटर/डार्ट पैकेज जो REST APIs के साथ बातचीत के लिए एक साफ अभिव्यक्ति प्रदान करता है। यह त्रुटि प्रबंधन और JWT प्रमाणीकरण के साथ स्वचालित रिफ्रेश टोकन समर्थन के साथ आम चुनौतियों को हल करता है। कई प्लेटफॉर्मों पर API संचार को सरल बनाने के लिए डिज़ाइन किया गया है, जिससे बॉयलरप्लेट कोड कम होता है और नेटवर्क ऑपरेशन में विश्वसनीयता बढ़ती है। सुरक्षित, स्थिर बैकएंड एकीकरण की आवश्यकता वाले ऐप्स के लिए आदर्श है।
उपयोग
प्रमाणित REST APIs के साथ एकीकरण
HTTP त्रुटियों को सम्मानजनक ढंग से संभालना
JWT टोकन रिफ्रेश करना स्वचालित करना
स्केलेबल बैकएंड इंटीग्रेशन बिल्ड करना
API रिक्वेस्ट लाइफसाइकल का प्रबंधन
क्रॉस-प्लेटफॉर्म नेटवर्क कॉल का समर्थन करना
मुख्य विशेषताएँ
निर्मित JWT और रिफ्रेश टोकन हैंडलिंग
व्यापक अपवाद संभाल
प्लेटफॉर्म के अनुकूलता
सरल, पुनः उपयोगी API क्लाइंट इंटरफेस
स्वचालित अनुरोध अवरोधन
कॉन्फ़िगरेबल बेस URL और हेडर्स
इनके लिए उपयुक्त
REST बैकएंड के साथ Flutter ऐप्स
सुरक्षित API एक्सेस की आवश्यकता वाले प्रोजेक्ट
नेटवर्किंग बॉयलरप्लेट को कम करने की तलाश में विकासकर्ता
बहु-प्लेटफॉर्म एप्लिकेशन बनाने वाली टीमें
JWT-आधारित प्रमाणीकरण का उपयोग करने वाले ऐप्स
विचार योग्य बातें
सही JWT टोकन सेटअप की आवश्यकता है
बाहरी http पैकेज पर निर्भर करता है
कस्टम त्रुटि मैपिंग की आवश्यकता हो सकती है
REST-शैली के एंडपॉइंट्स तक सीमित
गैर-HTTP प्रोटोकॉल्स के लिए अनुपयुक्त
प्रमाणीकरण प्रवाह को सर्वर तर्क के साथ संरेखित करना आवश्यक है
मूल README
संबंधित सोर्स रिपॉज़िटरी के मूल README का स्नैपशॉट। नवीनतम सामग्री के लिए रिपॉज़िटरी देखें।
Rest API Client
A production-ready HTTP client for Flutter applications that simplifies REST API communication with built-in support for JWT authentication, automatic token refresh, response caching, retry logic, and comprehensive error handling.
Features
JWT Authentication - Automatic token management with secure storage (Keychain/EncryptedSharedPreferences)
Token Refresh - Two strategies: response-and-retry or preemptive refresh before expiry
Response Caching - Intelligent caching with configurable expiration
Retry Logic - Exponential backoff for failed requests
// GET requestfinal result = await client.get('/users');
// GET with query parametersfinal result = await client.get('/users', queryParameters: {'page': 1, 'limit': 10});
// POST requestfinal result = await client.post('/users', data: {'name': 'John', 'email': 'john@example.com'});
// PUT requestfinal result = await client.put('/users/1', data: {'name': 'John Updated'});
// PATCH requestfinal result = await client.patch('/users/1', data: {'name': 'John Patched'});
// DELETE requestfinal result = await client.delete('/users/1');
// HEAD requestfinal result = await client.head('/users/1');
With Type Conversion
Use onSuccess to parse responses into typed objects:
final result = await client.get<User>(
'/users/1',
onSuccess: (data) => User.fromJson(data),
);
if (result.hasData) {
User user = result.data!;
print(user.name);
}
Per-Request Options
final result = await client.get(
'/users',
options: RestApiClientRequestOptions(
headers: {'X-Custom': 'value'},
contentType: 'application/json',
requiresAuth: false, // Skip authentication for this request
silentException: true, // Don't broadcast exceptions
),
);
Caching Strategies
Cache-First (Stale-While-Revalidate)
Returns cached data immediately, then fetches fresh data:
awaitfor (final result in client.getStreamed('/users')) {
if (result.hasData) {
// First emission: cached data (if available)// Second emission: fresh network dataupdateUI(result.data);
}
}
Cache-Only
Get data from cache only (no network request):
final result = await client.getCached('/users');
if (result.hasData) {
print('Cached data: ${result.data}');
}
Cache-Or-Network
Try cache first, fall back to network:
final result = await client.getCachedOrNetwork('/users');
Custom Cache Duration
final result = await client.get(
'/users',
cacheLifetimeDuration: Duration(hours: 1),
);
Authentication
Login Flow
// 1. Make login requestfinal loginResult = await client.post('/auth/login', data: {
'email': 'user@example.com',
'password': 'password123',
});
// 2. Authorize the client with received tokensif (loginResult.hasData) {
await client.authorize(
jwt: loginResult.data['accessToken'],
refreshToken: loginResult.data['refreshToken'],
);
}
// 3. All subsequent requests will include the JWTfinal userResult = await client.get('/users/me');
Check Authorization Status
final isLoggedIn = await client.isAuthorized();
Logout
await client.unAuthorize();
await client.clearStorage(); // Clear tokens and cached data
Error Handling
Result Object
All requests return a Result<T> object:
final result = await client.get('/users');
// Check for dataif (result.hasData) {
print(result.data);
}
// Check for errorsif (result.isError) {
print(result.exception);
}
// Check specific error typesif (result.isConnectionError) {
print('No internet connection');
}
// Access HTTP statusprint(result.statusCode); // e.g., 200, 404, 500print(result.statusMessage); // e.g., "OK", "Not Found"
Exception Types
Exception
HTTP Status
Description
ValidationException
400, 404, 422
Input validation errors
UnauthorizedException
401
Authentication required
ForbiddenException
403
Access denied
ServerErrorException
500, 502
Server-side errors
NetworkErrorException
-
Connection issues
Global Exception Stream
Listen to all exceptions across the app:
client.exceptionHandler.exceptions.stream.listen((exception) {
if (exception isUnauthorizedException) {
// Redirect to login
navigatorKey.currentState?.pushReplacementNamed('/login');
} elseif (exception isNetworkErrorException) {
// Show offline bannershowSnackBar('No internet connection');
}
});
Suppress Exceptions
// Suppress for a single requestfinal result = await client.get(
'/users',
options: RestApiClientRequestOptions(silentException: true),
);
File Downloads
final result = await client.download(
'/files/document.pdf',
'/path/to/save/document.pdf',
onReceiveProgress: (received, total) {
final progress = (received / total * 100).toStringAsFixed(0);
print('Download progress: $progress%');
},
);
Headers
// Set content type
client.setContentType('application/json');
// Set language
client.setAcceptLanguageHeader('en');
// Add custom header
client.addOrUpdateHeader(key: 'X-Api-Key', value: 'your-api-key');
// Access current headersprint(client.headers);