Ktor: что это, особенности асинхронного HTTP-клиента

Автор: IT Sectr Опубликовано: 2026-03-07 Время чтения: 8 мин

Ktor — это асинхронный HTTP-клиент для Kotlin, разработанный компанией JetBrains как часть одноимённого фреймворка для серверной и клиентской разработки. Ktor построен на корутинах Kotlin и поддерживает мультиплатформенность. По данным JetBrains, 2025, Ktor обеспечивает нативную интеграцию с Kotlin-экосистемой без рефлексии и дополнительных зависимостей.

Главное

  • Ktor — асинхронный HTTP-клиент на Kotlin с мультиплатформенной поддержкой
  • Корутины — основа выполнения запросов без колбэков и реактивных потоков
  • Плагины — модульная система расширения для сериализации, логирования и авторизации
  • Мультиплатформенность — один код для Android, iOS, Desktop и Server
  • Kotlinx Serialization — нативная сериализация без рефлексии через @Serializable

Что такое Ktor?

Ktor — это фреймворк для построения асинхронных серверных и клиентских приложений на Kotlin, созданный компанией JetBrains. Ktor Client — клиентская часть фреймворка, предоставляющая HTTP-клиент с полной поддержкой корутин Kotlin, мультиплатформенности (JVM, Native, JS) и модульной архитектуры на плагинах.

Ktor появился в 2018 году как альтернатива Retrofit и OkHttp для Kotlin-first проектов. В отличие от Retrofit, который портировал Java-подход с аннотациями, Ktor Client использует Kotlin DSL для конфигурации запросов — без аннотаций и рефлексии. Это делает код более читаемым и типобезопасным для Kotlin-разработчиков.

По данным опроса Kotlin Multiplatform 2024, Ktor Client используется в 35% проектов Kotlin Multiplatform Mobile (KMM), что делает его вторым по популярности HTTP-клиентом после OkHttp в Kotlin-сообществе. Ktor предпочитают в проектах, где важна мультиплатформенность и нативная интеграция с Kotlin-экосистемой.

Как работает Ktor Client

Архитектура 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 срабатывает только для защищённых эндпоинтов, не затрагивая публичные API.

Такой pipeline-подход позволяет комбинировать плагины гибко: вы можете установить ContentNegotiation с JSON, добавить Auth с Bearer-токеном, включить сжатие ContentEncoding и HttpTimeout — и все они будут работать совместно в правильном порядке. Порядок установки плагинов имеет значение: первый установленный будет обрабатывать запрос раньше остальных.

Плагины Ktor Client

Плагины — это модульная система расширения 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, но с типизированным Kotlin-API и поддержкой suspend-функций.

Кастомные плагины удобны для добавления метрик, автоматической ретрай-логики, трейсинга запросов или A/B-тестирования эндпоинтов. В отличие от перехватчиков OkHttp, Ktor-плагины написаны на Kotlin и работают в контексте корутины, что упрощает обработку ошибок и таймаутов.

Для отладки запросов используется плагин Logging с уровнем ALL, HEADERS или BODY. Logging выводит метод, URL, статус, заголовки и тело запроса и ответа. В отличие от HttpLoggingInterceptor из OkHttp, Ktor Logging работает асинхронно и может быть настроен на фильтрацию по уровню лога (ERROR, WARN, INFO, DEBUG) без остановки приложения для смены конфигурации.

Примеры кода Ktor Client на Kotlin

Рассмотрим базовый GET-запрос через Ktor Client. Создаётся HttpClient с установленным плагином ContentNegotiation для JSON. Запрос выполняется через suspend-функцию get(), результат автоматически десериализуется в data class.

kotlin
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 автоматически сериализует объект в JSON через установленный ContentNegotiation. DSL-стиль делает код последовательным и читаемым.

kotlin
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 для всех запросов, избавляя от дублирования кода в каждом вызове.

kotlin
val client = HttpClient {
    install(HttpTimeout) {
        connectTimeoutMillis = 15000
        requestTimeoutMillis = 30000
    }
    install(DefaultRequest) {
        url("https://api.github.com/")
        header("Accept", "application/json")
    }
}

Мультиплатформенная поддержка Ktor

Мультиплатформенность — главное преимущество 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. Это сокращает дублирование кода на 60–80% в KMM-проектах по сравнению с раздельными реализациями на Retrofit (Android) и URLSession (iOS). Плагины также работают на всех платформах без изменений.

Типовые ошибки при работе с Ktor

Игнорирование закрытия HttpClient — частая ошибка в Ktor. HttpClient реализует Closeable, и его нужно закрывать при завершении работы приложения через client.close(). В Android это делается в onDestroy() Activity или ViewModel.onCleared(). Незакрытый клиент приводит к утечке корутин и потоков движка.

Неправильный порядок плагинов может сломать обработку запроса. Например, ContentNegotiation должен быть установлен до DefaultRequest, чтобы тип контента применялся корректно. Logging рекомендуется устанавливать последним, чтобы логировать финальную версию запроса после всех модификаций. Экспериментируйте с порядком, если плагины ведут себя неожиданно.

Отсутствие обработки исключений в suspend-функциях. Ktor выбрасывает исключения IOException при сетевых ошибках и ClientRequestException при HTTP-статусах 4xx. Блок try-catch обязателен для каждого вызова get(), post() и других методов. Используйте HttpResponseValidator в блоке HttpClient для глобальной обработки ошибок без дублирования try-catch в каждом методе.

Часто задаваемые вопросы

Чем Ktor отличается от Retrofit?

Ktor использует Kotlin DSL и плагины без аннотаций и рефлексии. Retrofit построен на Java-аннотациях и рефлексии. Ktor поддерживает мультиплатформенность, Retrofit — только JVM/Android. Ktor нативно работает с корутинами, Retrofit добавил suspend через обёртку.

Какой движок Ktor лучше для Android?

Для Android оптимален OkHttp-движок — он обеспечивает совместимость с OkHttp-экосистемой, пул соединений, кэширование и HTTP/2. Выбирайте его через HttpClient(OkHttp) { }. Альтернатива — CIOEngine, встроенный в Ktor, но он менее стабилен на Android.

Поддерживает ли Ktor HTTP/2?

Да, Ktor поддерживает HTTP/2 через соответствующий движок. OkHttp-движок наследует поддержку HTTP/2 от OkHttp. DarwinEngine на iOS поддерживает HTTP/2 через URLSession. CIOEngine поддерживает HTTP/2 на серверной стороне. Выбор движка определяет уровень поддержки протокола.

Как настроить авторизацию в Ktor Client?

Используйте плагин Auth с установкой bearer { }. Плагин автоматически добавляет заголовок Authorization к каждому запросу и может обновлять токен при ответе 401 через refreshTokens. Пример: install(Auth) { bearer { loadTokens { BearerTokens(token, refreshToken) } } }.

Можно ли использовать Ktor Client на iOS?

Да, Ktor Client полноценно работает на iOS через DarwinEngine, использующий URLSession. Все плагины, сериализация и корутины работают на iOS так же, как на Android. Это делает Ktor основным HTTP-клиентом для Kotlin Multiplatform Mobile (KMM) проектов.

Итоги

  • Ktor — асинхронный HTTP-клиент от JetBrains с мультиплатформенной поддержкой
  • Kotlin DSL заменяет аннотации — конфигурация через программные блоки без рефлексии
  • Плагины ContentNegotiation, Auth, Logging и HttpTimeout модульно расширяют функциональность
  • Корутины — основа выполнения: все методы suspend без колбэков и реактивных потоков
  • Мультиплатформенность — один код для Android, iOS, Desktop, Server и JS
  • Движки OkHttp, Darwin, CIO адаптируют Ktor под конкретную платформу
  • HttpResponseValidator централизует обработку HTTP-ошибок без дублирования try-catch

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также