Ktor یک کلاینت HTTP ناهمزمان برای Kotlin است که توسط شرکت JetBrains به عنوان بخشی از فریمورک همنام برای توسعه سمت سرور و کلاینت ساخته شده است. Ktor بر پایه کوروتینهای Kotlin ساخته شده و از چندسکویی پشتیبانی میکند. بر اساس دادههای JetBrains, 2025، Ktor یکپارچگی بومی با اکوسیستم Kotlin را بدون بازتاب (reflection) و وابستگیهای اضافی فراهم میکند.
نکات کلیدی
Ktor یک فریمورک برای ساخت برنامههای ناهمزمان سمت سرور و کلاینت در Kotlin است که توسط شرکت JetBrains ساخته شده است. Ktor Client — بخش کلاینت فریمورک است که یک کلاینت HTTP با پشتیبانی کامل از کوروتینهای Kotlin، چندسکویی (JVM, Native, JS) و معماری ماژولار مبتنی بر پلاگین ارائه میدهد.
Ktor در سال 2018 به عنوان جایگزینی برای Retrofit و OkHttp در پروژههای Kotlin-first ظاهر شد. بر خلاف Retrofit که رویکرد Java را با نویسهها (annotation) port کرده بود، Ktor Client از Kotlin DSL برای پیکربندی درخواستها استفاده میکند — بدون نویسه و بازتاب. این کار کد را برای توسعهدهندگان Kotlin خواناتر و نوع-ایمنتر میکند.
بر اساس نظرسنجی Kotlin Multiplatform 2024، Ktor Client در 35% پروژههای Kotlin Multiplatform Mobile (KMM) استفاده میشود که آن را به دومین کلاینت HTTP محبوب بعد از OkHttp در جامعه Kotlin تبدیل میکند. Ktor در پروژههایی که چندسکویی و یکپارچگی بومی با اکوسیستم Kotlin مهم است ترجیح داده میشود.
معماری Ktor Client بر اساس خط لوله (pipeline) از پلاگینها است. هر درخواست از دنبالهای از پلاگینهای نصب شده عبور میکند که میتوانند درخواست، پاسخ را تغییر دهند یا اقدامات جانبی انجام دهند — لاگینگ، فشردهسازی، سریالایز، احراز هویت.
هنگام ایجاد کلاینت HTTP از طریق بلوک HttpClient { } DSL، موتور (OkHttp, Android, CIO, Darwin) را مشخص کرده و پلاگینها را نصب میکنید. هر موتور ارسال سطح پایین درخواست را برای یک پلتفرم خاص پیادهسازی میکند: در Android از موتور OkHttp استفاده میشود، در iOS — Darwin (URLSession)، در Desktop — CIO (Coroutine-based I/O). HttpClient به طور خودکار موتور بهینه را برای پلتفرم جاری انتخاب میکند.
درخواست در Ktor Client از طریق تابع suspend اجرا میشود که به معنای یکپارچگی کامل با کوروتینها است. هیچ Callback، RxJava یا LiveData — فقط کد ترتیبی با suspend که بدون مسدود کردن رشته به صورت ناهمزمان کار میکند.
خط لوله Ktor از فازها تشکیل شده است: ابتدا درخواست از پلاگینهای نصب شده عبور میکند (مثلاً ContentNegotiation برای JSON، Logging برای لاگها)، سپس موتور درخواست HTTP را اجرا میکند و پاسخ دوباره برای سریالزدایی از پلاگینها عبور میکند. هر پلاگین یک تابع suspend است که در کوروتین خط لوله اجرا میشود.
مزیت مهم خط لوله Ktor امکان پردازش شرطی است. پلاگین میتواند URL یا هدرهای درخواست را بررسی کند و اگر شرط برآورده نشد، پردازش را رد کند. مثلاً ContentEncoding با gzip فقط به پاسخهایی اعمال میشود که هدر Content-Encoding: gzip را دارند، و Auth فقط برای endpointهای محافظتشده فعال میشود و بر APIهای عمومی تأثیر نمیگذارد.
این رویکرد خط لوله امکان ترکیب انعطافپذیر پلاگینها را فراهم میکند: میتوانید ContentNegotiation با JSON نصب کنید، Auth با توکن Bearer اضافه کنید، فشردهسازی ContentEncoding و HttpTimeout را فعال کنید — و همه آنها با هم به ترتیب درست کار خواهند کرد. ترتیب نصب پلاگینها مهم است: اولین نصب شده درخواست را زودتر از بقیه پردازش میکند.
پلاگینها — سیستم توسعه ماژولار Ktor هستند که جایگزین نویسههای Retrofit و رهگیرهای OkHttp میشوند. هر پلاگین یک کار خاص را حل میکند و از طریق تابع install() در بلوک HttpClient نصب میشود. Ktor پلاگینهای داخلی ارائه میدهد و همچنین امکان ایجاد پلاگینهای سفارشی را فراهم میکند.
| پلاگین | کاربرد |
|---|---|
| ContentNegotiation | سریالایز و سریالزدایی JSON، XML از طریق Kotlinx Serialization |
| Logging | لاگ کردن درخواستها و پاسخها با تنظیم سطح |
| Auth | احراز هویت: Basic, Bearer, Digest با بهروزرسانی خودکار توکن |
| HttpTimeout | تنظیم مهلتهای اتصال، خواندن و درخواست |
| ContentEncoding | فشردهسازی شفاف gzip و deflate |
| DefaultRequest | تنظیم مقادیر پیشفرض برای همه درخواستها |
برای کارهای خاص از طریق createClientPlugin یک پلاگین سفارشی ساخته میشود. پلاگین میتواند درخواست (onRequest)، پاسخ (onResponse) را رهگیری کند یا خطاها (onError) را مدیریت کند. این کاملاً جایگزین Interceptor از OkHttp میشود، اما با API تایپشده Kotlin و پشتیبانی از توابع suspend.
پلاگینهای سفارشی برای افزودن معیارها، منطق خودکار تلاش مجدد، ردیابی درخواستها یا تست A/B endpointها مفید هستند. بر خلاف رهگیرهای OkHttp، پلاگینهای Ktor به زبان Kotlin نوشته شده و در زمینه کوروتین کار میکنند که مدیریت خطا و مهلتها را سادهتر میکند.
برای اشکالزدایی درخواستها از پلاگین Logging با سطح ALL، HEADERS یا BODY استفاده میشود. Logging متد، URL، وضعیت، هدرها و بدنه درخواست و پاسخ را نشان میدهد. بر خلاف HttpLoggingInterceptor از OkHttp، Ktor Logging به صورت ناهمزمان کار میکند و میتواند برای فیلتر بر اساس سطح لاگ (ERROR, WARN, INFO, DEBUG) بدون توقف برنامه برای تغییر پیکربندی تنظیم شود.
درخواست GET پایه را از طریق Ktor Client بررسی میکنیم. یک HttpClient با پلاگین ContentNegotiation نصب شده برای JSON ایجاد میشود. درخواست از طریق تابع suspend get() اجرا میشود، نتیجه به طور خودکار به data class سریالزدایی میشود.
data class User(
val login: String,
val id: Int,
val avatarUrl: String
)
val client = HttpClient {
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
})
}
}
suspend fun getUser(): User {
return client.get("https://api.github.com/users/octocat").body()
}
برای درخواست POST با بدنه از تابع post() با contentType() و body() استفاده میشود. Ktor به طور خودکار شیء را از طریق ContentNegotiation نصب شده به JSON سریالایز میکند. سبک DSL کد را ترتیبی و خواناتر میکند.
data class CreateRepo(
val name: String,
val description: String,
val private: Boolean
)
suspend fun createRepo(): Unit {
val repo = CreateRepo(
name = "my-project",
description = "Sample project",
private = false
)
client.post("https://api.github.com/user/repos") {
contentType(ContentType.Application.Json)
setBody(repo)
}
}
HttpTimeout و DefaultRequest — دو پلاگین کلیدی برای پیکربندی. HttpTimeout محدودیتهای زمانی را تعیین میکند و DefaultRequest هدرها و پارامترهای URL را برای همه درخواستها تنظیم میکند و از تکرار کد در هر فراخوانی جلوگیری میکند.
val client = HttpClient {
install(HttpTimeout) {
connectTimeoutMillis = 15000
requestTimeoutMillis = 30000
}
install(DefaultRequest) {
url("https://api.github.com/")
header("Accept", "application/json")
}
}
چندسکویی — مزیت اصلی Ktor نسبت به OkHttp و Retrofit. Ktor Client روی JVM (Android, Server)، Native (iOS, macOS, Windows, Linux) و JS (Browser) کار میکند. همان کد کلاینت HTTP روی همه پلتفرمها بدون تغییر اجرا میشود که به ویژه برای پروژههای Kotlin Multiplatform ارزشمند است.
برای هر پلتفرم Ktor از موتور (engine) خود استفاده میکند. در Android به طور پیشفرض موتور OkHttp اعمال میشود که سازگاری کامل با اکوسیستم OkHttp ارائه میدهد. در iOS از DarwinEngine مبتنی بر URLSession استفاده میشود. برای Server — CIOEngine (Coroutine I/O). موتور را میتوان به صراحت مشخص کرد: HttpClient(OkHttp) { } یا HttpClient(Darwin) { }.
هنگام انتخاب موتور قابلیتهای آن را در نظر بگیرید: موتور OkHttp از HTTP/2 و استخر اتصالات پشتیبانی میکند، DarwinEngine — یکپارچگی بومی با شبکه iOS و جلسات پسزمینه URLSession، CIOEngine — پیادهسازی خالص کوروتینی بدون وابستگیهای خارجی. برای هدفهای Web از JsEngine یا BrowserEngine استفاده میشود که از طریق fetch API کار میکنند.
به لطف API یکسان در همه پلتفرمها، کد بارگذاری داده در Android، iOS و Desktop یکسان به نظر میرسد. این کار تکرار کد را در پروژههای KMM تا 60–80% در مقایسه با پیادهسازیهای جداگانه در Retrofit (Android) و URLSession (iOS) کاهش میدهد. پلاگینها نیز بدون تغییر در همه پلتفرمها کار میکنند.
نادیده گرفتن بستن HttpClient — خطای رایج در Ktor. HttpClient اینترفیس Closeable را پیادهسازی میکند و باید پس از اتمام کار برنامه از طریق client.close() بسته شود. در Android این کار در onDestroy() Activity یا ViewModel.onCleared() انجام میشود. کلاینت بسته نشده منجر به نشت کوروتینها و رشتههای موتور میشود.
ترتیب نادرست پلاگینها میتواند پردازش درخواست را مختل کند. مثلاً ContentNegotiation باید قبل از DefaultRequest نصب شود تا نوع محتوا به درستی اعمال شود. توصیه میشود Logging را آخرین نصب کنید تا نسخه نهایی درخواست پس از همه تغییرات لاگ شود. اگر پلاگینها غیرمنتظره رفتار میکنند، با ترتیب آزمایش کنید.
عدم مدیریت استثناها در توابع suspend. Ktor در خطاهای شبکه IOException و در وضعیتهای HTTP 4xx ClientRequestException پرتاب میکند. بلوک try-catch برای هر فراخوانی get()، post() و سایر متدها اجباری است. از HttpResponseValidator در بلوک HttpClient برای مدیریت سراسری خطاها بدون تکرار try-catch در هر متد استفاده کنید.
سوالات متداول
Ktor از Kotlin DSL و پلاگینها بدون نویسه و بازتاب استفاده میکند. Retrofit بر روی نویسههای Java و بازتاب ساخته شده است. Ktor از چندسکویی پشتیبانی میکند، Retrofit — فقط JVM/Android. Ktor به صورت بومی با کوروتینها کار میکند، Retrofit suspend را از طریق یک لایه wrapper اضافه کرده است.
برای Android موتور OkHttp بهینه است — سازگاری با اکوسیستم OkHttp، استخر اتصالات، کش و HTTP/2 را فراهم میکند. آن را از طریق HttpClient(OkHttp) { } انتخاب کنید. جایگزین — CIOEngine داخلی Ktor، اما روی Android کمتر پایدار است.
بله، Ktor از HTTP/2 از طریق موتور مربوطه پشتیبانی میکند. موتور OkHttp پشتیبانی HTTP/2 را از OkHttp به ارث میبرد. DarwinEngine در iOS از HTTP/2 از طریق URLSession پشتیبانی میکند. CIOEngine از HTTP/2 در سمت سرور پشتیبانی میکند. انتخاب موتور سطح پشتیبانی پروتکل را تعیین میکند.
از پلاگین Auth با تنظیم bearer { } استفاده کنید. پلاگین به طور خودکار هدر Authorization را به هر درخواست اضافه میکند و میتواند توکن را در پاسخ 401 از طریق refreshTokens بهروزرسانی کند. مثال: install(Auth) { bearer { loadTokens { BearerTokens(token, refreshToken) } } }.
بله، Ktor Client به طور کامل در iOS از طریق DarwinEngine که از URLSession استفاده میکند کار میکند. همه پلاگینها، سریالایز و کوروتینها در iOS مانند Android کار میکنند. این Ktor را به کلاینت HTTP اصلی برای پروژههای Kotlin Multiplatform Mobile (KMM) تبدیل میکند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید