הגדרת Dio לבקשות רשת ב-Flutter
בכל פרויקט Flutter שמתקשר עם שרת, עולה בהכרח השאלה: איך לארגן ביעילות את שכבת הרשת? החבילה הסטנדרטית http חסרה מנגנונים מובנים לאימות, ניסיונות חוזרים, רישום לוגים וביטול בקשות — מפתחים בסופו של דבר כותבים כמות עצומה של קוד תבניתי. Dio פותר את הבעיות האלה: זהו לקוח HTTP חזק עם אינטרספטורים, תמיכה ב-CancelToken, FormData להעלאת קבצים, וטיפול גמיש בשגיאות. במשך יותר מ-5 שנות עבודה עם Flutter ויותר מ-20 הטמעות של Dio, גילינו שאימוץ Dio מקצץ את נפח הקוד לפעולות רשת פי 2–3 ומאיץ את הפיתוח בעד 40%. Dio מעבד בקשות פי 1.5–2 מהר יותר מחבילת ה-http הרגילה לפי בדיקות ביצועים מפרויקטים טיפוסיים. לדוגמה, בשליחת 5 בקשות מקבילות, Dio משלים אותן ב-30% מהר יותר הודות למאגר החיבורים המובנה שלו. אנו מגדירים Dio מקצה לקצה תוך 1–2 ימים — צרו קשר כדי להעריך את הפרויקט שלכם. באמצעות Dio תוכלו לחסוך עד $500 בעלויות פיתוח בהשוואה לבניית שכבת רשת מותאמת אישית מאפס.
למה Dio, לא http?
Dio מבטל קוד תבניתי: במקום טיפול ידני בכותרות ובקודי סטטוס — אינטרספטורים; במקום טיימרים לניסיונות חוזרים — מנגנונים מובנים. השוו:
| היבט | http | Dio |
|---|---|---|
| אינטרספטורים | לא | כן |
| ביטול בקשות | ידני דרך cancel | CancelToken |
| ניסיון חוזר | מסורבל | dio_smart_retry |
| העלאה עם התקדמות | לא | onSendProgress |
יתר על כן, Dio מקצר את זמן הפיתוח של שכבת הרשת ב-30–50% לפי המדידות שלנו, ומספר שורות הקוד עבור CRUD טיפוסי יורד פי 2.5. אם בפרויקט שלכם יש יותר מ-10 נקודות קצה API, המעבר ל-Dio משתלם תוך שבוע.
הגדרת אינטרספטורים לאימות
אינטרספטורים הם המפתח לקוד נקי. דוגמה ל-AuthInterceptor:
class AuthInterceptor extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
final token = tokenStorage.accessToken;
if (token != null) {
options.headers['Authorization'] = 'Bearer $token';
}
handler.next(options);
}
@override
void onError(DioException err, ErrorInterceptorHandler handler) async {
if (err.response?.statusCode == 401) {
try {
await tokenStorage.refresh();
final opts = err.requestOptions;
opts.headers['Authorization'] = 'Bearer ${tokenStorage.accessToken}';
final response = await dio.fetch(opts);
handler.resolve(response);
return;
} catch (_) {
// refresh failed — logout
}
}
handler.next(err);
}
}לרישום לוגים במצב פיתוח, השתמשו ב-class AuthInterceptor extends Interceptor { @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { final token = tokenStorage.accessToken; if (token != null) { options.headers['Authorization'] = 'Bearer $token'; } handler.next(options); } @override void onError(DioException err, ErrorInterceptorHandler handler) async { if (err.response?.statusCode == 401) { try { await tokenStorage.refresh(); final opts = err.requestOptions; opts.headers['Authorization'] = 'Bearer ${tokenStorage.accessToken}'; final response = await dio.fetch(opts); handler.resolve(response); return; } catch (_) { // refresh failed — logout } } handler.next(err); } } עם רמת פירוט הניתנת להגדרה. לניסיונות חוזרים, השתמשו ב-LogInterceptor: מאפשר עד 5 ניסיונות עם השהיה אקספוננציאלית (לדוגמה, 1 שנייה, 2 שניות, 4 שניות). אנו מגדירים רכיבים אלה כך שיעבדו בצורה חלקה עם הארכיטקטורה שלכם, בין אם אתם משתמשים ב-BLoC, Riverpod או Provider.
העלאת קבצים וביטול בקשות
// Multipart upload с прогрессом
final formData = FormData.fromMap({
'file': await MultipartFile.fromFile(filePath, filename: 'photo.jpg'),
});
await dio.post(
'/upload',
data: formData,
onSendProgress: (sent, total) {
progress.value = sent / total;
},
);
// Отмена запроса
final cancelToken = CancelToken();
dio.get('/data', cancelToken: cancelToken);
// Позже:
cancelToken.cancel('User navigated away');CancelToken חיוני לבקשות הקשורות למחזור החיים של ווידג'ט. עבור קבצים עד 10 מגה-בייט, העלאה עם התקדמות מאפשרת הצגת אחוזים מדויקת. אי ביטול בקשות ב-dio_smart_retry מוביל לדליפות זיכרון ול-// Multipart upload с прогрессом final formData = FormData.fromMap({ 'file': await MultipartFile.fromFile(filePath, filename: 'photo.jpg'), }); await dio.post('/upload', data: formData, onSendProgress: (sent, total) { progress.value = sent / total; }, ); // Отмена запроса final cancelToken = CancelToken(); dio.get('/data', cancelToken: cancelToken); // Позже: cancelToken.cancel('User navigated away'); פוטנציאלי לאחר dispose. בפרויקטים עם בקשות רבות (50+), שימוש ב-CancelToken מפחית את צריכת הזיכרון ב-15–20%.
טיפול בשגיאות רשת
DioException מכיל שדה dispose() — חשוב להבחין:
| סוג | גורם | פעולה |
|---|---|---|
| connectionTimeout | אין אינטרנט או שהשרת לא זמין | הצגת הודעה, ניסיון חוזר אחרי 30 שניות |
| badResponse | השרת החזיר 4xx/5xx | ניתוח ה-body, הצגת שגיאה |
| cancel | הבקשה בוטלה | התעלם |
עבור שגיאות 5xx, הגדירו ניסיון חוזר עם מקסימום 3 ניסיונות וזמן ожидание הולך וגדל. עטפו בשכבת דומיין כדי למנוע תלות ב-Dio ב-BLoC/Cubit:
Future<Either<Failure, T>> safeCall<T>(Future<T> Function() request) async {
try {
return Right(await request());
} on DioException catch (e) {
return Left(NetworkFailure.fromDioException(e));
}
}גישה זו מבודדת את הלוגיקה העסקית מפרטי היישום של לקוח ה-HTTP ומפשטת את הבדיקות. תיעוד Dio ממליץ על תבנית דומה.
מה כלול בעבודת הגדרת Dio?
- ניתוח ארכיטקטורה — קביעה כיצד שכבת הרשת משתלבת במבנה שלכם (BLoC, Riverpod, Provider).
- הגדרה בסיסית — singleton עם timeouts, כותרות, כתובת URL בסיסית.
- אינטרספטורים — יישום אימות (Bearer token, refresh), רישום לוגים, ניסיונות חוזרים. בדרך כלל עד 5 אינטרספטורים.
- טיפול בשגיאות —
setStateעם מיפוי שגיאות לשכבת הדומיין, כתיבת 10+ בדיקות יחידה. - בדיקות — בדיקות יחידה לאינטרספטורים ובדיקות אינטגרציה עם שרת מדומה.
- תיעוד — תיאור API ודוגמאות שימוש.
- מסירה — שכבת רשת ניתנת לפריסה עם הפרדת אחריות ברורה.
כל שלב מסתיים בהדגמה על הפרויקט שלכם. הניסיון שלנו — יותר מ-20 הטמעות מוצלחות של Dio — מבטיח שתקבלו תשתית רשת אמינה וניתנת להרחבה. הזמינו הגדרת Dio — החל מ-$500 (בסיסי) או $1500 (אינטגרציה מלאה עם ניסיונות חוזרים, טיפול בשגיאות ובדיקות). עם יותר מ-5 שנות ניסיון ב-Flutter ויותר מ-20 פרויקטי Dio, אנו בשוק כבר למעלה מ-5 שנים, ומספקים פתרונות חזקים.
טעויות נפוצות בהגדרת Dio
- אי הקצאת CancelToken — דליפת זיכרון בעת יציאה ממסך (עד 50% עלייה בזיכרון).
- התעלמות מסוג DioException — אובדן ההבחנה בין timeout לשגיאת שרת.
- אחסון token בזיכרון — לאחר הפעלה מחדש של האפליקציה, נדרש אימות מחדש.
- אי טיפול גלובלי ב-401 — כל בקשה עלולה לזרוק חריגה שלא טופלה.
הימנעות מטעויות אלה מעניקה לכם שכבת רשת יציבה שלא תיכשל בייצור.
ציר זמן ועלות
הגדרה בסיסית עם אינטרספטור אימות ורישום לוגים: מ-4 עד 8 שעות (החל מ-$500). עם ניסיונות חוזרים, טיפול בשגיאות ואינטגרציה ארכיטקטונית: מ-1 עד 2 ימים (החל מ-$1500). העלות מחושבת באופן אישי — קבלו ייעוץ כדי להעריך את הפרויקט שלכם. עבדנו עם Flutter במשך יותר מ-5 שנים והשלמנו יותר מ-20 פרויקטי Dio. צרו קשר כדי ליישם Dio באופן מקצועי.







