Ktor — یک کلاینت HTTP ناهمگام و فریمورک سرور برای Kotlin است که از توسعه چندسکویی پشتیبانی میکند. این کتابخانه بر پایه کوروتینهای Kotlin ساخته شده و روی JVM، iOS، Android، JS و Native کار میکند. بر اساس دادههای مخزن Ktor در گیتهاب، این پروژه به طور فعال توسط تیم JetBrains توسعه مییابد. Ktor معماری ماژولار با سیستم افزونهای برای پیکربندی انعطافپذیر اتصالات HTTP ارائه میدهد.
نکات کلیدی
Ktor — فریمورکی برای ایجاد کلاینتهای HTTP و سرورها به زبان Kotlin است که توسط شرکت JetBrains توسعه یافته است. برخلاف کتابخانههای سنتی، Ktor از ابتدا برای توسعه چندسکویی طراحی شده است و روی تمام پلتفرمهای پشتیبانی شده توسط Kotlin کار میکند.
Ktor از رویکرد میانافزارهای پردازشی استفاده میکند که از معماری Kodein و Express.js الهام گرفته شده است. هر درخواست از یک خط لوله از توابع پردازشگر عبور میکند که میتوانند درخواست و پاسخ را تغییر دهند. این انعطافپذیری را فراهم میکند که در کتابخانههای با معماری سفت و سخت مبتنی بر حاشیهنویسی در دسترس نیست.
نسخه فعلی Ktor 3.0 شامل پشتیبانی از Kotlin 2.0، کامپایلر K2 و موتور جدید CIO (Coroutine I/O) با عملکرد بهبود یافته است. این کتابخانه تحت مجوز Apache 2.0 منتشر شده و برای استفاده تجاری بدون محدودیت در دسترس است.
بخش کلاینت Ktor کاملاً بر پایه کوروتینهای Kotlin ساخته شده است که اجرای ناهمگام کارآمد درخواستها را بدون مسدود کردن رشتهها تضمین میکند. بخش سرور امکان ایجاد سرورهای HTTP با مسیریابی، پردازش درخواستها و اتصالات WebSocket را فراهم میکند.
Ktor از معماری افزونهای استفاده میکند: تمام ویژگیهای اضافی — لاگگیری، سریالسازی، احراز هویت — از طریق افزونهها متصل میشوند. این باعث میشود کتابخانه ماژولار باشد و امکان اتصال فقط اجزای ضروری را فراهم کند و اندازه برنامه نهایی را کاهش دهد.
به لطف API یکپارچه در تمام پلتفرمها، توسعهدهنده نیازی به یادگیری کلاینتهای HTTP متفاوت برای iOS و Android ندارد. در یک پروژه چندسکویی، کد لایه شبکه کاملاً مشترک است و پیادهسازی مختص پلتفرم در پشت موتور HttpClient پنهان شده است. این باعث کاهش زمان توسعه و کاهش تعداد خطاهای مرتبط با تفاوتهای پلتفرم میشود.
Ktor مجموعهای از قابلیتها را ارائه میدهد که آن را به انتخابی جذاب برای پروژههای مدرن Kotlin، به ویژه پروژههای چندسکویی تبدیل میکند.
Ktor روی JVM، Android، iOS، macOS، Windows، Linux، JavaScript و Wasm کار میکند. همان کد کلاینت HTTP بدون تغییر روی تمام پلتفرمها اجرا میشود. این مزیت کلیدی نسبت به کتابخانههای وابسته به OkHttp یا URLSession است.
کوروتینهای Kotlin ناهمگامی طبیعی را بدون فراخوان بازگشتی فراهم میکنند. هر درخواست یک تابع suspend است که میتوان از هر کوروتینی فراخوانی کرد. Ktor از جریانسازی پاسخها از طریق Flow پشتیبانی میکند که برای اتصالات طولانی و WebSocket مناسب است.
افزونههای Ktor از طریق بلوک install متصل شده و جداگانه پیکربندی میشوند. افزونههای اصلی: ContentNegotiation برای سریالسازی، Logging برای لاگگیری، Auth برای احراز هویت و WebSockets برای ارتباط دوطرفه. هر افزونه را میتوان مستقل فعال یا غیرفعال کرد.
مدیریت خطا در Ktor بر پایه استثناها است. کلاس ClientRequestException برای کدهای 4xx، ServerResponseException برای 5xx و IOException برای خطاهای شبکه پرتاب میشود. مهلتهای زمانی از طریق افزونه HttpTimeout پیکربندی میشوند که زمان انتظار برای اتصال، خواندن و نوشتن را تعیین میکند. برای تلاش مجدد از افزونه Retry با تنظیمات تعداد تلاش و تأخیر استفاده میشود.
Ktor از معماری خط لوله استفاده میکند که در آن هر درخواست از زنجیرهای از پردازشگرها عبور میکند. کلاینت یک پیکربندی HttpClient با افزونههای نصب شده ایجاد میکند و هر فراخوانی متد get یا post از افزونهها به ترتیب اتصال آنها عبور میکند.
شیء HttpClient با موتوری خاص برای پلتفرم ایجاد میشود: CIO برای JVM و Android، Darwin برای iOS و macOS، OkHttp برای سازگاری با Android، Js برای مرورگر. موتور را میتوان به صراحت انتخاب کرد یا انتخاب خودکار را واگذار کرد. هر درخواست HttpResponse را برمیگرداند که شامل بدنه پاسخ، هدرها و وضعیت است.
val client = HttpClient(CIO) {
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
})
}
}
suspend fun fetchUsers(): List<User> {
return client.get("https://api.example.com/users").body()
}
نصب Ktor از طریق Gradle یا Maven انجام میشود. در پروژههای چندسکویی، وابستگیها در sourceSets برای هر هدف مشخص میشوند. Ktor از طریق Maven Central منتشر میشود.
در build.gradle.kts وابستگی ktor-client-core را برای کد مشترک و موتور را برای پلتفرم خاص اضافه کنید. نسخه Ktor از طریق متغیری در gradle.properties تنظیم میشود. Ktor 3.x به Kotlin 2.0+ نیاز دارد و از کامپایلر K2 پشتیبانی میکند.
val ktorVersion = "3.0.3"
dependencies {
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-cio:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
implementation("io.ktor:ktor-client-logging:$ktorVersion")
}
برای iOS از موتور Darwin استفاده میشود که URLSession بومی را کپسوله میکند. در Kotlin Multiplatform این امکان حداکثر عملکرد و یکپارچگی با مکانیزمهای کش سیستمی iOS را فراهم میکند. موتور به عنوان یک وابستگی جداگانه در sourceSet iOS اضافه میشود.
یکی از ویژگیهای مهم Ktor — پشتیبانی از فرمتهای مختلف سریالسازی از طریق ContentNegotiation. علاوه بر JSON، این افزونه از Protobuf، CBOR، XML و فرمتهای سفارشی پشتیبانی میکند. برای سریالسازی از کتابخانههای kotlinx.serialization یا Jackson استفاده میشود و توسعهدهنده میتواند بدون تغییر کد درخواستها بین آنها جابهجا شود.
نمونههای زیر سناریوهای معمول کار با کلاینت Ktor را نشان میدهند: درخواست GET پایه، ارسال داده و کار با کد چندسکویی.
یک درخواست GET ساده با دسریالسازی خودکار پاسخ به کلاس داده. Ktor از افزونه ContentNegotiation با kotlinx.serialization برای تبدیل JSON به اشیاء استفاده میکند. کد مختصر و نوعامن است.
@Serializable
data class Post(
val id: Int,
val title: String,
val body: String
)
suspend fun getPosts(): List<Post> {
val response = client.get("https://jsonplaceholder.typicode.com/posts")
return response.body()
}
درخواست POST در Ktor کلاس داده را به عنوان بدنه JSON از طریق متد post با contentType و setBody ارسال میکند. افزونه ContentNegotiation به طور خودکار شیء را به رشته JSON سریال میکند. پاسخ را میتوان به صورت همگام یا ناهمگام پردازش کرد.
suspend fun createPost(): Post {
val newPost = Post(
id = 0,
title = "پست جدید",
body = "محتوای پست"
)
val response = client.post("https://jsonplaceholder.typicode.com/posts") {
contentType(ContentType.Application.Json)
setBody(newPost)
}
return response.body()
}
متد submitFormWithBinaryData در Ktor امکان ارسال فایلها و فرمها را در قالب multipart فراهم میکند. Ktor به طور خودکار دادهها را به بخشها تقسیم کرده و هدرها را اضافه میکند. برای پیگیری پیشرفت از onUpload استفاده میشود که بایتهای دادههای ارسالی را دریافت میکند.
suspend fun uploadFile(fileBytes: ByteArray) {
client.submitFormWithBinaryData(
url = "https://api.example.com/upload",
formData = formData {
append("file", fileBytes, Headers.build {
append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=\"photo.png\"")
})
}
)
}
انتخاب بین Ktor و Retrofit به معماری پروژه و نیازهای چندسکویی بستگی دارد. Retrofit استاندارد پروژههای فقط Android باقی میماند، در حالی که Ktor انتخاب بهتری برای Kotlin Multiplatform است.
Ktor همچنین پشتیبانی داخلی از WebSocket و SSE (رویدادهای ارسالشده توسط سرور) را فراهم میکند که آن را برای برنامههای بلادرنگ مناسب میکند. Retrofit مستقیماً از WebSocket پشتیبانی نمیکند — برای این کار به کتابخانه جداگانه OkHttp WebSocket نیاز است. Ktor همچنین به دلیل سیستم افزونهای که هر افزونه مسئول یک عملکرد است، برای محیطهای مختلف راحتتر پیکربندی میشود.
افزونه Auth در Ktor از احراز هویت پایه، توکنهای Bearer، Digest و OAuth2 پشتیبانی میکند. پیکربندی احراز هویت به صورت اعلانی انجام میشود: توسعهدهنده ارائهدهنده، منبع توکن و محدوده عمل را مشخص میکند. Ktor به طور خودکار هدرهای احراز هویت را به درخواستها اضافه میکند و میتواند توکن را هنگام انقضا بهروزرسانی کند.
اگر پروژه از Kotlin Multiplatform با کد مشترک در iOS و Android استفاده میکند، Ktor تنها گزینهای است که بدون لایههای اضافی روی هر دو پلتفرم کار میکند. Retrofit به شدت به OkHttp و JVM وابسته است که آن را برای iOS نامناسب میکند.
برای پروژههای فقط Android، Retrofit API بالغتر، تعداد بیشتری مبدل و رهگیرهای OkHttp ارائه میدهد. Ktor در این سناریو نیز کار میکند، اما اکوسیستم افزونه آن کمتر گسترده است. هر دو کتابخانه از کوروتینها پشتیبانی میکنند و عملکرد قابل مقایسهای ارائه میدهند.
| معیار | Ktor | Retrofit |
|---|---|---|
| چندسکویی | iOS، Android، JVM، JS، Native | فقط JVM و Android |
| موتور HTTP | CIO، Darwin، OkHttp، Js | OkHttp |
| مبدلها | kotlinx.serialization، Jackson | Gson، Moshi، Jackson، Protobuf |
| معماری | خط لوله با افزونهها | حاشیهنویسی با تولید کد |
| توسعهدهنده | JetBrains | Square |
سوالات متداول
Ktor — یک کلاینت HTTP چندسکویی بر پایه کوروتینها از JetBrains. Retrofit — کتابخانه Android از Square بر اساس OkHttp. Ktor روی iOS، Android، JS و Native کار میکند، در حالی که Retrofit فقط روی JVM.
بله، Ktor از iOS از طریق موتور Darwin که از URLSession بومی استفاده میکند پشتیبانی میکند. این حداکثر عملکرد و کار صحیح با کش سیستمی iOS را تضمین میکند. کد کلاینت بین پلتفرمها مشترک باقی میماند.
Ktor از موتورهای CIO (JVM/Android)، Darwin (iOS/macOS)، OkHttp (Android)، Js (مرورگر)، Jetty، Netty، Tomcat (سرور) پشتیبانی میکند. موتور را میتوان به صراحت انتخاب کرد یا انتخاب خودکار پیشفرض را واگذار کرد.
بله، Ktor پشتیبانی داخلی از WebSocket را هم در کلاینت و هم در سرور دارد. برای کلاینت از افزونه WebSockets استفاده میشود که امکان برقراری ارتباط دوطرفه و تبادل پیام در زمان واقعی را فراهم میکند.
خطاها از طریق try-catch در اطراف فراخوانیهای suspend مدیریت میشوند. Ktor استثناهای ClientRequestException را برای 4xx، ServerResponseException را برای 5xx و IOException را برای خطاهای شبکه پرتاب میکند. برای یکپارچهسازی استفاده از نوع Result توصیه میشود.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید