Retrofit هو عميل HTTP آمن من حيث النوع لتطبيقات Android، تم تطويره بواسطة Square بلغة Java. تتيح المكتبة تعريف REST APIs من خلال واجهات Java مع التعليقات التوضيحية، وتحويل استجابات HTTP تلقائياً إلى كائنات Java. وفقاً لـ مستودع Retrofit على GitHub، يُستخدم المشروع في أكثر من 42,000 مشروع حول العالم. تظل المكتبة المعيار لطلبات الشبكة في تطوير Android.
النقاط الرئيسية
Retrofit هي مكتبة لإجراء طلبات HTTP في تطبيقات Android، تم تطويرها بواسطة Square. توفر نهجاً تصريحياً لتعريف REST APIs من خلال واجهات Java مع التعليقات التوضيحية، مما يجعل كود التفاعل الشبكي نظيفاً وقابلاً للتنبؤ.
الفكرة الأساسية لـ Retrofit هي أن المطور يصف API كـ واجهة مع دوال وتعليقات توضيحية، وتقوم المكتبة بتوليد التنفيذ تلقائياً. يضمن هذا النهج أن جميع endpoints مقيدة النوع، ويتم اكتشاف الأخطاء في URL أو المعاملات في وقت الترجمة وليس في وقت التشغيل.
يدعم Retrofit جميع طرق HTTP الشائعة وتنسيقات البيانات. تتم صيانة المكتبة بنشاط من قبل Square والمجتمع: تصدر الإصدارات الجديدة بانتظام، والإصدار الحالي 2.11 يتضمن دعم Java 17 وKotlin 2.0. يظل Retrofit أكثر عميل HTTP شيوعاً لنظام Android.
يعمل Retrofit فوق OkHttp، وهو عميل HTTP فعال من Square أيضاً. يوفر هذا المزيج التخزين المؤقت، اعتراض الطلبات، وإدارة الاتصالات على مستوى بروتوكول النقل. تدعم المكتبة كلاً من الاستدعاءات المتزامنة وغير المتزامنة.
منذ إصداره الأول في 2013، مر Retrofit بعدة تحديثات رئيسية. تمت إعادة كتابة الإصدار الحالي Retrofit 2 بالكامل بناءً على تجربة الإصدار الأول ويقدم نظاماً أكثر مرونة للمحولات والمهايئات للتعامل مع عدم التزامن.
تتبع بنية Retrofit مبدأ فصل المسؤوليات: الواجهة تحدد فقط عقد API، والمحولات تتولى التسلسل، والمهايئات تدير عدم التزامن. هذا يتيح استبدال أي مكون دون تغيير باقي الكود. على سبيل المثال، يمكنك الانتقال من Gson إلى Moshi دون تغيير تعريفات endpoints.
Retrofit يوفر مجموعة من الميزات التي تغطي جميع سيناريوهات التفاعل الشبكي تقريباً في التطبيقات المحمولة. الميزة الرئيسية هي الأسلوب التصريحي لتعريف API.
التعليقات التوضيحية @GET و@POST و@PUT و@PATCH و@DELETE و@HTTP تسمح بتحديد طريقة HTTP ونمط URL مباشرة في الواجهة. تُعيّن معاملات المسار عبر @Path، ومعاملات الاستعلام عبر @Query، وجسم الطلب عبر @Body. هذا النهج يجعل طبقة API في التطبيق مقيدة النوع بالكامل.
المحولات تحول استجابات HTTP إلى كائنات Java والعكس. يدعم Retrofit Gson وMoshi وJackson وProtobuf وWire. يقوم المطور بتوصيل المحول المطلوب عبر Converter.Factory، وتقوم المكتبة بتطبيقه تلقائياً على جميع الطلبات والاستجابات.
المهايئات CallAdapter تسمح بتغيير نوع القيمة المُعادة لدوال API. بدلاً من Call القياسي، يمكن استخدام Observable لـ RxJava، أو Deferred لـ coroutines في Kotlin، أو LiveData. هذا يدمج طلبات الشبكة مع بنية التطبيق المختارة.
عناوين URL الديناميكية تُعيّن عبر التعليق التوضيحي @Url، مما يتيح تمرير endpoint في وقت التشغيل. يمكن تحديد الرؤوس بشكل ثابت عبر @Headers أو ديناميكياً عبر المعامل @Header. للرؤوس العامة عبر جميع الطلبات، يُستخدم معترض OkHttp الذي يضيف رؤوساً إلى كل طلب صادر.
Retrofit يعمل على ثلاث مراحل: تعريف واجهة API، إنشاء مثيل Retrofit، وتنفيذ الطلب. تقوم المكتبة بتوليد تنفيذ الواجهة في وقت التشغيل بناءً على التعليقات التوضيحية والمحولات.
عند استدعاء دالة API، يقوم Retrofit بإنشاء كائن Request بناءً على التعليقات التوضيحية والوسائط. يُمرر الطلب إلى OkHttp للتنفيذ. بعد تلقي الاستجابة، تمررها المكتبة إلى Converter.Factory لتحويلها إلى النوع المطلوب. يغلف CallAdapter النتيجة في غلاف غير متزامن. يمكن تخصيص كل مرحلة.
interface ApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") id: Int): User
}
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val api = retrofit.create(ApiService::class.java)
تثبيت Retrofit يتم من خلال Gradle، نظام البناء القياسي لـ Android. يتم توزيع المكتبة عبر Maven Central وتتطلب إضافة عدة تبعيات إلى build.gradle للمشروع.
في ملف build.gradle (على مستوى الوحدة)، أضف تبعيات لـ Retrofit ومحول Gson وOkHttp. يُوصى باستخراج إصدارات المكتبات في متغيرات في build.gradle الجذر لإدارة مركزية. يتطلب Retrofit 2 كحد أدنى Android API 21.
dependencies {
implementation "com.squareup.retrofit2:retrofit:2.11.0"
implementation "com.squareup.retrofit2:converter-gson:2.11.0"
implementation "com.squareup.okhttp3:okhttp:4.12.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.12.0"
}
يتم إنشاء مثيل Retrofit من خلال Builder. المعاملات الإلزامية: baseUrl وConverterFactory. يُوصى باستخدام singleton لـ Retrofit وOkHttpClient لتجنب إنشاء اتصالات زائدة. إضافة logging-interceptor يبسط تصحيح أخطاء طلبات الشبكة أثناء التطوير.
لمشاريع Kotlin، يُوصى باستخدام دوال suspend في واجهة API بدلاً من أنواع Call. هذا يبسط الكود ويتيح استخدام التزامن المنظم لـ coroutines. عند الانتقال من Call إلى suspend، يكفي تغيير نوع القيمة المُعادة في الواجهة — باقي الكود يتكيف تلقائياً.
الأمثلة أدناه توضح سيناريوهات نموذجية للعمل مع Retrofit في تطبيقات Android: من طلب GET بسيط إلى رفع ملف إلى الخادم.
طلب GET بسيط مع معاملات سلسلة الاستعلام هو عملية أساسية. يضيف التعليق التوضيحي @Query المعاملات إلى URL تلقائياً، وتسمح دالة suspend باستدعاء الطلب من coroutine دون حظر الخيط الرئيسي.
interface UserApi {
@GET("users")
suspend fun getUsers(
@Query("page") page: Int,
@Query("limit") limit: Int = 20
): List<User>
}
val users = api.getUsers(page = 1)
طلب POST مع جسم JSON يستخدم التعليق التوضيحي @Body لتمرير الكائن. يقوم GsonConverterFactory بتسلسل كائن User إلى JSON تلقائياً. تضمن coroutines في Kotlin تنفيذ الطلب في خلفية دون واجهات Callback.
interface UserApi {
@POST("users")
suspend fun createUser(@Body user: User): User
}
val user = User(name = "آنا إيفانوفا", email = "anna@example.com")
val created = api.createUser(user)
التعليق التوضيحي @Multipart مع @Part يتيح رفع الملفات إلى الخادم. يقوم Retrofit بتشكيل طلب multipart تلقائياً مع الرؤوس المطلوبة. يدير OkHttp تقدم الرفع عبر RequestBody، مما يتيح عرض مؤشر للمستخدم.
interface FileApi {
@Multipart
@POST("upload")
suspend fun uploadImage(
@Part file: MultipartBody.Part
): UploadResponse
}
val body = "image.jpg".toRequestBody("image/jpeg".toMediaTypeOrNull())
val part = MultipartBody.Part.createFormData("file", "image.jpg", body)
معالجة الأخطاء في Retrofit تُبنى على مزيج من آليات OkHttp وcoroutines في Kotlin. تسمح معترضات OkHttp بتسجيل الطلبات وإضافة رؤوس المصادقة ومعالجة الأخطاء قبل وصولها إلى كود التطبيق.
لمعالجة الأخطاء المركزية، غالباً ما يُنشأ غلاف حول استدعاءات API كـ كلاس مغلق Result. يحتوي هذا الكلاس على فرعين: Success مع البيانات وError مع استثناء. يتلقى ViewModel نتيجة موحدة ويمكنه عرض حالة واجهة المستخدم المقابلة دون تكرار كود معالجة الأخطاء في كل دالة.
المعترضات من نوعين: معترضات التطبيق تعدل الطلب قبل إرساله إلى الخادم، ومعترضات الشبكة تعمل مع الاستجابة بعد استلامها. على سبيل المثال، يمكن للمعترض تحديث رمز الوصول تلقائياً عند استلام 401 وإعادة الطلب بالرمز الجديد دون تدخل المطور.
معترض التسجيل HttpLoggingInterceptor هو أداة لا غنى عنها لتصحيح أخطاء طلبات الشبكة. يُخرج في Logcat طريقة الطلب وURL والرؤوس والجسم ورمز الاستجابة. يمكن تكوين مستوى التسجيل: BASIC لمعلومات بسيطة، HEADERS للرؤوس، أو BODY للمحتوى الكامل. في الإنتاج، يُوصى باستخدام BASIC أو تعطيل التسجيل تماماً.
المعترضات في OkHttp تنقسم إلى نوعين: معترضات التطبيق لتعديل الطلب ومعترضات الشبكة للعمل مع بيانات الشبكة الخام. يقوم معترض التسجيل تلقائياً بإخراج تفاصيل الطلب والاستجابة في Logcat.
معالجة الأخطاء على مستوى coroutines تتم من خلال try-catch حول استدعاء دالة suspend. يُرجع Retrofit الأخطاء كـ HttpException للرموز 4xx و5xx، وUnknownHostException عند عدم وجود شبكة، وSocketTimeoutException عند تجاوز المهلة. يُوصى باستخدام كلاس مغلق Result للمعالجة الموحدة.
الأسئلة الشائعة
Retrofit هو غلاف عالي المستوى فوق OkHttp. يقوم OkHttp بعمليات HTTP منخفضة المستوى، بينما يضيف Retrofit تعليقات توضيحية تصريحية ومحولات ومهايئات. عادةً، تستخدم المشاريع كلتا المكتبتين معاً.
الأخطاء تُعالج من خلال try-catch حول استدعاء suspend. يُوصى باستخدام كلاس Result لإرجاع البيانات الناجحة أو الخطأ. هذا يتجنب كتل catch متعددة في كل ViewModel.
Retrofit يدعم Gson وMoshi وJackson وProtobuf وWire وSimple XML وScalars. كل محول يُوصل عبر Converter.Factory. الأكثر شيوعاً هما GsonConverterFactory وMoshiConverterFactory.
لا، Retrofit مرتبط بإحكام بـ OkHttp ولا يدعم عملاء HTTP آخرين. للمشاريع متعددة المنصات في Kotlin، استخدم Ktor الذي يعمل على جميع المنصات بما في ذلك iOS وJS.
المهلة تُضبط من خلال OkHttpClient. عيّن خصائص connectTimeout وreadTimeout وwriteTimeout عند إنشاء العميل، ثم مرره إلى Retrofit.Builder.client(). القيم الافتراضية هي 10 ثوانٍ.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا