عميل HTTP بلغة Kotlin: إجراء الطلبات بشكل صحيح — المستوى المتقدم

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

عميل HTTP بلغة Kotlin: إجراء الطلبات بشكل صحيح — المستوى المتقدم



عند تطوير التطبيقات الحديثة بلغة Kotlin، يتجاوز العمل مع طلبات HTTP بكثير مجرد استدعاء URL.readText(). على المستوى المتقدم، يجب مراعاة إدارة الاتصالات، والمهلات، وإعادة المحاولات، والتسجيل، وعدم التزامن، والمعالجة الصحيحة للأخطاء. في هذه المقالة، سنشرح كيفية إعداد عميل HTTP بلغة Kotlin لبيئة الإنتاج باستخدام مكتبتين شائعتين: OkHttp و Ktor Client. المادة موجهة للمطورين الملمين بالفعل بأساسيات Kotlin وHTTP.



1. اختيار المكتبة: OkHttp مقابل Ktor Client

قبل كتابة الكود، من المهم فهم الفرق بين النهجين. OkHttp هي مكتبة ناضجة ومختبرة عبر الزمن من Square، وتعمل بشكل ممتاز مع Retrofit. Ktor Client هي مكتبة أصلية متعددة المنصات من JetBrains، ومتكاملة بالكامل مع coroutines في Kotlin. للمشاريع الخادمية على Spring Boot، غالبًا ما يتم اختيار OkHttp، بينما لتطبيقات Ktor أو المشاريع متعددة المنصات، يتم اختيار Ktor Client.



سننظر في كلا الخيارين حتى تتمكن من اختيار الأنسب لمكدسك التقني.



2. الإعداد المتقدم لـ OkHttp

الإعداد الأساسي لـ OkHttp بسيط، ولكن للإنتاج يتطلب تكوينًا دقيقًا. سننظر في إنشاء عميل Singleton بمعلمات مخصصة.



import okhttp3.*import java.util.concurrent.TimeUnit

object HttpClientProvider {

private val client: OkHttpClient by lazy { OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .retryOnConnectionFailure(true) .addInterceptor(LoggingInterceptor()) .addInterceptor(RetryInterceptor(maxRetries = 3)) .connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES)) .build() }

fun getClient(): OkHttpClient = client}


2.1 المعترضات المخصصة (Interceptors)

المعترضات هي آلية قوية لتعديل الطلبات والاستجابات. فيما يلي مثال على معترض تسجيل ومعترض لإعادة المحاولات.



class LoggingInterceptor : Interceptor {    override fun intercept(chain: Interceptor.Chain): Response {        val request = chain.request()        println("--> ${request.method} ${request.url}")        val startTime = System.nanoTime()        val response = chain.proceed(request)        val duration = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)        println("<-- ${response.code} ${response.message} (${duration}ms)")        return response    }}

class RetryInterceptor(private val maxRetries: Int) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { var retryCount = 0 var response: Response? = null while (retryCount < maxRetries) { try { response = chain.proceed(chain.request()) if (response.isSuccessful) return response } catch (e: Exception) { println("Retry #${retryCount + 1} failed: ${e.message}") } retryCount++ if (retryCount < maxRetries) Thread.sleep(1000L * retryCount) } return response ?: throw IOException("Max retries exceeded") }}


2.2 الطلبات غير المتزامنة مع coroutines

يدعم OkHttp الطلبات المتزامنة وغير المتزامنة (القائمة على الاستدعاء). للتكامل مع Kotlin coroutines، نستخدم suspendCancellableCoroutine.



suspend fun makeRequest(url: String): String {    return suspendCancellableCoroutine { continuation ->        val request = Request.Builder().url(url).build()        val call = HttpClientProvider.getClient().newC                

المدونات

توصيات الكتب