Организация сетевого взаимодействия с помощью Ktor
10.11.2023|7 минут
Android Kotlin Мой опыт
Предупреждение
Эта статья устарела и оставлена лишь в целях сохранения истории. Лучше ориентироваться на более новую версию
Введение
Я сейчас параллельно с изучением .NET работаю над мобильным приложением для своего проекта. Для разработки я выбрал новый фреймворк от Google Jetpack Compose в том числе потому, что не хочу тратить лишнее время на описание интерфейсов через XML или ручное управление состоянием приложения. Он предоставляет декларативный интерфейс для проектирования интерфейса через более удобный Kotlin.
В мире Android-разработки обычно используется Retrofit или OkHttp, но я решил взять Ktor от JetBrains. Практически никаких готовых туториалов по этому стеку не было, поэтому я пишу свой.
Установка зависимостей
Добавим в build.gradle.kts уровня модуля следующие зависимости:
На момент написания этой статьи уже вышла версия ktor 2.3.5, но она вызывала странные ошибки компиляции, поэтому пришлось откатиться.
Настройка клиента
В Ktor создание клиента это ресурсоёмкий процесс, поэтому важно не закрывать его в течение всего жизненного цикла приложения. Можно было использовать Hilt, который уже использовался в проекте на момент добавления работы с сетью, но я взял более простой способ.
Kotlin позволяет создавать объекты, которые автоматически будут создаваться на старте приложения и всё время держаться в памяти. Поэтому добавим объект HttpClientFactory. У меня он расположен в пакете domain.common.network
С помощью этого объекта мы сможем в любом месте получать один и тот же объект клиента и использовать его для запросов в сеть.
Организация типизированных запросов
Добавим класс Response, который будет содержать информацию о типах, в которые необходимо преобразовывать данные, пришедшие с сервера
Напишем пару методов расширения для HTTP клиента.
Так, метод safeRequest поможет, используя стандартный синтаксис запросов ktor делать запросы в сеть, добавляя при этом обработку ошибок.
Метод errorBody для объекта исключения ResponseException позволяет получать корректное сообщение об ошибке.
Обработка ответов
Добавим функцию, которая позволит нам обрабатывать ответ от сервера и получать конкретный тип результата
Добавление моделей запросов/ответов
Для того, чтобы корректно работала сериализация моделей в JSON нужно пометить их аннотацией @Serializable:
Классы, которые не имеют собственной реализации в Kotlin, а просто взяты из Java не имеют своих сериализаторов, поэтому их нужно написать самостоятельно. Я для первичных ключей использую UUID, поэтому приведу реализацию его сериализатора:
Описание клиента
Добавим сервисы, которые будут содержать описание API и правила подключения к нему. Для каждого такого сервиса описываем интерфейс и его реализацию:
Чтобы не загромождать статью огромной портянкой кода я приведу лишь часть реализации сервиса:
Выполнение запросов
Данные запрашиваются из viewmodels экранов с помощью асинхронных функций: