Retrofit: ما هو، ميزات عميل HTTP لنظام Android

المؤلف: IT Sectr نُشر: 2026-03-07 وقت القراءة: 8 دق

Retrofit هو عميل HTTP مكتوب لتطبيقات Android وKotlin، طورته شركة Square. تتيح المكتبة تحويل REST API إلى واجهة بلغة Java أو Kotlin باستخدام التعليقات التوضيحية. وفقًا لـ Square, 2025، يُستخدم Retrofit في آلاف التطبيقات كأداة قياسية للعمل مع طلبات HTTP.

الوجبات الرئيسية

  • Retrofit هو عميل HTTP مكتوب من Square لـ Android وKotlin مع واجهة برمجية تصريحية
  • التعليقات التوضيحية @GET و@POST و@Path و@Query تصف طلبات HTTP بدون كود boilerplate
  • المحولات Gson وMoshi وKotlinx Serialization تحول JSON إلى كائنات Kotlin
  • OkHttp هو طبقة النقل الإلزامية التي تنفذ جميع طلبات HTTP تحت غطاء Retrofit
  • دوال Suspend تدمج Retrofit مع coroutines في Kotlin للاستدعاءات غير المتزامنة

ما هو Retrofit؟

Retrofit هي مكتبة للتفاعل المكتوب مع REST API على منصة Android، طورتها Square. توفر طريقة تصريحية لوصف طلبات HTTP من خلال واجهات Java أو Kotlin مع التعليقات التوضيحية، مما يلغي تمامًا الحاجة إلى تحليل JSON يدويًا وإدارة اتصالات HTTP.

ظهرت المكتبة في عام 2013 كبديل للحلول المعقدة مثل AsyncTask وHttpURLConnection. بحلول عام 2025، لا يزال Retrofit المعيار الفعلي للاتصال بالشبكة في تطبيقات Android بفضل بساطته وأمان أنواعه. وفقًا لاستطلاع JetBrains Developer Ecosystem 2024، يستخدم أكثر من 65% من مطوري Android Retrofit في المشاريع التجارية.

الفرق الرئيسي بين Retrofit والبدائل هو النهج التصريحي: يصف المطور ما يجب فعله (أي endpoint استدعاء، أي معلمات تمرير) بدلاً من كيفية القيام به (كيفية فتح اتصال، كيفية قراءة InputStream، كيفية تحليل JSON). هذا يقلل كود boilerplate بنسبة 60–70% مقارنة بالاستخدام اليدوي لـ HttpURLConnection.

كيف يعمل Retrofit

مبدأ العمل يعتمد Retrofit على الوكلاء الديناميكيين في Java. عندما يستدعي المطور إحدى طرق واجهة موصوفة بالتعليقات التوضيحية، يعترض Retrofit الاستدعاء عبر آلية Proxy.newProxyInstance ويحوله إلى طلب HTTP. تحدث العملية بأكملها في وقت التشغيل بدون توليد كود في وقت الترجمة.

عند إنشاء مثيل Retrofit.Builder، يتم تحديد URL الأساسي ومصنع المحول. يقوم Builder بتكوين OkHttpClient — تعيين المهلات والمعترضات ومجمع الاتصالات وذاكرة التخزين المؤقت. يقوم الأسلوب create(Class) بتوليد تنفيذ الواجهة، وإرجاع كائن وكيل يمكن استدعاؤه كفئة عادية.

سلسلة تنفيذ الطلب تبدو كالتالي: تستخرج التعليقات التوضيحية أسلوب HTTP، تستبدل المعلمات في URL أو نص الطلب، يقوم المحول بتسلسل النص، ينفذ OkHttp الطلب، يقوم المحول بإلغاء تسلسل الاستجابة، ويعود النتيجة في النوع المحدد. كل مرحلة معزولة ويمكن استبدالها بتنفيذ مخصص، مثلاً استبدال OkHttpClient بـ MockWebServer للاختبار أو تغيير المحول عند تغيير API.

ميزة مهمة — Retrofit لا يدعم نقل البيانات بشكل متدفق مباشرة. للتدفق، يُستخدم OkHttp ResponseBody كنوع إرجاع لأسلوب الواجهة. كما أن Retrofit لا يدير إلغاء الطلبات تلقائيًا — للإلغاء يجب الاحتفاظ بمرجع لـ Call واستدعاء cancel(). في Kotlin مع دوال suspend، يحدث إلغاء الطلب تلقائيًا عند إلغاء coroutine الأب.

دورة حياة كائن Call

Call<T> هو كائن يمثل طلب HTTP واحد. بعد التنفيذ (execute أو enqueue)، لا يمكن إعادة استخدام Call — للطلب المتكرر يجب إنشاء Call جديد عبر استدعاء أسلوب الواجهة. هذا يمنع الإرسال العرضي لنفس الطلب مرتين، مما قد يؤدي إلى عمليات مكررة على الخادم.

في Kotlin، بدلاً من Call تُستخدم دوال suspend، التي تدير تلقائيًا دورة حياة الطلب. يقوم Retrofit بتبديل التنفيذ إلى Dispatchers.IO وإرجاع النتيجة إلى coroutine. هذا يقلل الكود بنسبة 30–40% مقارنة بإصدار Call وCallback.

تعليقات Retrofit التوضيحية لأساليب HTTP

التعليقات التوضيحية هي الآلية الرئيسية لتكوين طلبات HTTP في Retrofit. كل تعليق توضيحي يتوافق مع أسلوب HTTP قياسي ويقبل مسارًا نسبيًا إلى endpoint. يدعم Retrofit GET وPOST وPUT وDELETE وPATCH وHEAD وOPTIONS.

التعليق التوضيحيأسلوب HTTPالغرض
@GETGETجلب البيانات من الخادم
@POSTPOSTإنشاء مورد جديد
@PUTPUTتحديث مورد بالكامل
@DELETEDELETEحذف مورد
@PATCHPATCHتحديث مورد جزئيًا

تعليقات معلمات الطلب

@Path يستبدل قيمة في جزء URL: @Path("id") Int id يستبدل {id} في المسار. @Query يضيف معلمة استعلام: @Query("page") Int page يتحول إلى ?page=5. @Body يمرر كائنًا في نص الطلب مع تسلسل تلقائي عبر المحول المختار. @Header و@Headers يديران رؤوس HTTP — ثابتة أو ديناميكية.

بدمج هذه التعليقات التوضيحية، يمكن وصف أي endpoint REST. على سبيل المثال، لنقطة النهاية POST /api/users/{id}/posts?limit=10 تحتاج إلى @POST و@Path لـ id و@Query لـ limit و@Body للكائن الممرر. سيقوم Retrofit تلقائيًا بتجميع طلب HTTP صحيح. كما تُدعم @Url (URL ديناميكي) و@Field (نص مشفر بنموذج) و@Part و@PartMap للطلبات متعددة الأجزاء مع الملفات.

أمثلة كود Retrofit بلغة Kotlin

لنلقِ نظرة على مثال عملي — واجهة لـ API GitHub. يتم إنشاء واجهة Kotlin بأسلوب لجلب قائمة المستودعات. تصف فئة البيانات Repo هيكل استجابة JSON.

kotlin
data class Repo(
    val name: String,
    val description: String?,
    val stargazersCount: Int,
    val forksCount: Int
)

interface GitHubApi {
    @GET("users/{user}/repos")
    suspend fun getRepos(
        @Path("user") user: String,
        @Query("sort") sort: String = "updated"
    ): List<Repo>
}

بعد وصف الواجهة، يتم إنشاء مثيل Retrofit عبر Builder. يتم تكوين URL الأساسي والمحول وOkHttpClient مرة واحدة وإعادة استخدامها عبر حقن التبعيات.

kotlin
val retrofit = Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .client(OkHttpClient.Builder()
        .connectTimeout(30, TimeUnit.SECONDS)
        .build())
    .build()

val api = retrofit.create(GitHubApi::class.java)

معالجة الاستجابة بغلاف Response

لمعالجة مرنة لأكواد حالة HTTP، استخدم غلاف Response<T>. يوفر الوصول إلى كود الاستجابة والرؤوس والنص بدون رمي استثناءات عند أخطاء 4xx و5xx. هذا يسمح بمعالجة 404 و500 بدون try-catch.

kotlin
interface GitHubApi {
    @GET("users/{user}/repos")
    suspend fun getRepos(
        @Path("user") user: String
    ): Response<List<Repo>>
}

val response = api.getRepos("octocat")
if (response.isSuccessful) {
    println(response.body()?.size)
} else {
    Log.e("API", "Error: ${response.code()}")
}

المحولات والتسلسل في Retrofit

المحولات هي مكونات Retrofit المسؤولة عن تحويل الكائنات إلى نص HTTP والعكس. لا يدمج Retrofit التسلسل في نواته — بل يستخدم نهجًا معياريًا عبر Converter.Factory، مما يسمح بتوصيل أي مكتبة تسلسل.

المحول الأكثر شيوعًا هو GsonConverterFactory من Google المبني على مكتبة Gson. يعمل لمعظم المشاريع، ويدعم TypeAdapter وJsonDeserializer مخصصين. ومع ذلك، يستخدم Gson الانعكاس ولا يراعي أمان القيم الخالية في Kotlin، مما قد يؤدي إلى NPE في حال وجود حقول فارغة غير متوقعة.

بديل هو MoshiConverterFactory من Square: أكثر صرامة مع الأنواع، وبدعم أفضل لـ Kotlin (أمان القيم الخالية، القيم الافتراضية) وبدون انعكاس. للمشاريع بلغة Kotlin النقية، الخيار الأمثل هو Kotlinx Serialization Converter، الذي يعمل مع تعليقات @Serializable في وقت الترجمة. لا يستخدم انعكاسًا، ويدعم sealed class والقيم الافتراضية وتعدد المنصات.

اختيار المحول يؤثر على الأداء وأمان الأنواع. Gson بدون تكوين مخصص يمكن أن يحول null إلى حقل غير فارغ في Kotlin، مسببًا NPE عند الوصول. يحل Moshi هذه المشكلة من خلال تعليق @Json(name) وfailOnUnknown. Kotlinx Serialization هو الأكثر أمانًا — يولد كودًا في وقت الترجمة، مما يلغي تمامًا أخطاء الأنواع في وقت التشغيل.

الأخطاء الشائعة عند العمل مع Retrofit

عدم معالجة أخطاء HTTP في دوال suspend هو المشكلة الأكثر شيوعًا. إذا أعاد الخادم 4xx أو 5xx، يرمي Retrofit HttpException. بدون try-catch، يتعطل التطبيق. استخدام Response<T> كنوع إرجاع يحل هذه المشكلة، مما يسمح بالتحقق من isSuccessful قبل الوصول إلى النص.

التكوين غير الصحيح للتخزين المؤقت يؤدي إلى حركة مرور زائدة. لا يخزن Retrofit الاستجابات مؤقتًا بنفسه — هذه المهمة يقوم بها OkHttpClient عبر Cache. بدون ذاكرة تخزين مؤقت، يتم تنفيذ كل طلب بالكامل، حتى عندما لم تتغير البيانات. إضافة ذاكرة تخزين مؤقت بحجم 10 ميجابايت في OkHttpClient تقلل حركة المرور بنسبة 40–60% عند الطلبات المتكررة لنفس المعلومات.

إنشاء Retrofit لكل طلب هو خطأ شائع للمبتدئين. Retrofit.Builder عملية مكلفة تتضمن توليد فئات وكيلة في وقت التشغيل. الممارسة الصحيحة هي إنشاء مثيل Retrofit واحد وإعادة استخدامه عبر أطر DI. Hilt أو Koin أو Dagger توفر مثيل singleton من Retrofit للتطبيق بأكمله، مما يوفر الذاكرة ويسرع الطلبات.

تجاهل Interceptor للتفويض هو المشكلة الرابعة. بدلاً من إضافة رأس Authorization يدويًا لكل استدعاء، قم بتكوين Interceptor عام في OkHttpClient. يعترض Interceptor كل طلب، ويضيف رمز Bearer، ويتعامل Authenticator مع استجابة 401، ويجدد الرمز ويكرر الطلب تلقائيًا. هذا يركز منطق المصادقة.

الأسئلة الشائعة

كيف يختلف Retrofit عن OkHttp؟

Retrofit هو طبقة علوية فوق OkHttp توفر واجهة برمجية تصريحية عبر التعليقات التوضيحية. OkHttp هو عميل HTTP منخفض المستوى يعمل مع Request وResponse مباشرة. يبسط Retrofit الكتابة والتسلسل ومعالجة الاستجابات، مستخدمًا OkHttp كنقل.

أي محول تختار لـ Retrofit؟

لمشاريع Java — GsonConverterFactory. لـ Kotlin مع Moshi — MoshiConverterFactory (أكثر أمانًا مع الأنواع). الخيار الأمثل لـ Kotlin النقي هو Kotlinx Serialization Converter. يعمل بدون انعكاس، ويدعم sealed class والقيم الافتراضية.

هل يدعم Retrofit coroutines؟

نعم، بدءًا من الإصدار 2.6.0 يدعم Retrofit دوال suspend. قم بتعريف الأسلوب كـ suspend، وسينفذ Retrofit الطلب على Dispatchers.IO، معيدًا النتيجة إلى coroutine. لا حاجة لاستخدام Call وenqueue — يصبح الكود تسلسليًا.

كيفية إعداد التفويض في Retrofit؟

يُضاف التفويض عبر Interceptor في OkHttp. في intercept()، أضف رأس Authorization. للرموز الديناميكية، استخدم Authenticator في OkHttp — يعترض استجابة 401 ويجدد الرمز تلقائيًا، مكررًا الطلب بالرأس الجديد.

هل يمكن استخدام Retrofit بدون OkHttp؟

لا — يستخدم Retrofit دائمًا OkHttp كطبقة نقل. يتم تمرير OkHttpClient عبر Builder.client() ويدير المهلات والمعترضات والتخزين المؤقت ومجمع الاتصالات. بدون OkHttp، لا يمكن لـ Retrofit تنفيذ أي طلب.

الخلاصة

  • Retrofit هو عميل HTTP مكتوب من Square لـ Android وKotlin مع واجهة برمجية تصريحية قائمة على التعليقات التوضيحية
  • التعليقات التوضيحية @GET و@POST و@Path و@Query و@Body تصف طلبات REST بدون كود boilerplate
  • الوكلاء الديناميكيون في Java يحولون استدعاءات طرق الواجهة إلى طلبات HTTP في وقت التشغيل
  • المحولات Gson وMoshi وKotlinx Serialization توفر تسلسل JSON إلى كائنات
  • OkHttp هو طبقة النقل الإلزامية مع المعترضات والتخزين المؤقت ومجمع الاتصالات
  • دوال Suspend تدمج استدعاءات HTTP غير المتزامنة مع coroutines في Kotlin
  • غلاف Response يعالج أخطاء HTTP 4xx و5xx بدون استثناءات غير معالجة

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا