Мы слишком долго использовали такие технологии, как Retrofit и Volley, и отрасль также очень эффективно адаптировала их. Тем не менее, с интенсивным ростом популярности Kotlin среди Android-разработчиков появился новый API для совершения сетевых вызовов в Kotlin: Ktor-client.
JetBrains каждый день стремительно развивает Kotlin. Это один из самых любимых языков в мире, покоривший сердца разработчиков Android. Однако там его не ограничили. Мы также можем создать внутренний сервер с Kotlin с API под названием Ktor, а Ktor-client — это его клиентская версия.
Настройка Ktor-клиента
Как обычно, нам нужно установить зависимости для Ktor-client. В этом уроке мы будем использовать следующие зависимости:
def ktor_version = "1.6.8" implementation "io.ktor:ktor-client-core:$ktor_version" implementation "io.ktor:ktor-client-android:$ktor_version" implementation "io.ktor:ktor-client-serialization:$ktor_version" implementation "io.ktor:ktor-client-logging:$ktor_version" implementation "ch.qos.logback:logback-classic:1.2.9"
Ktor-client способствует использованию реализующих модулей, поэтому мы используем только те модули, которые необходимы, а не все, что есть в Ktor.
Создание интерфейса
Хотя для Ktor-client не требуется создавать интерфейс, рекомендуется использовать этот шаблон проектирования.
interface ApiService { suspend fun getPost(id: String): Response<PostDto> suspend fun createPost(post: Post): Response<PostDto> }
и теперь мы можем реализовать этот интерфейс в конкретном классе. Здесь мы совершим настоящий сетевой вызов.
class ApiServiceImpl( private val client: HttpClient ) : ApiService { override suspend fun getPost(id: String): Response<PostDto> { return try { val response = client.get<PostDto> { url("$BASE_URL/posts/$id/?key=value") } return Response.Success(response) } catch (e: RedirectResponseException) { // 3xx Response.Error(e.response.status.description) } catch (e: ClientRequestException) { // 4xx Response.Error(e.response.status.description) } catch (e: ServerResponseException) { // 5xx Response.Error(e.response.status.description) } } [...] }
Ktor-client — это библиотека на основе Kotlin, которая использует все предоставляемые ею функции. Чтобы сделать HTTP-вызов GET
, мы используем функцию suspend fun get()
для объекта client
. Функция будет анализировать входящие данные в общий параметр. Лямбда-функция компоновщика имеет метод url()
, который принимает URL-адрес String
с параметрами пути и параметрами запроса — необработанный URL-адрес.
Создание объекта клиента
Обычно я бы посоветовал вам сделать это с внедрением зависимостей, но сейчас я сделаю companion object
внутри интерфейса ApiService
.
interface ApiService { [...] companion object { val client = HttpClient(Android) { install(Logging) { level = LogLevel.ALL } install(JsonFeature) { serializer = KotlinxSerializer() } } } }
Завершение
Теперь вы можете завершить все и начать сетевой вызов. Скажите, что вы хотите получать сообщения всякий раз, когда пользователь нажимает кнопку:
btnGetPost.setOnClickListener { _ -> lifecycleScope.launch { ApiService.client.use { val service = ApiServiceImpl(it) when (val response = service.getPost("2")) { is Response.Success -> { /* do something */ } is Response.Error -> toast(response.message) } } } }
Делаем POST-запрос
Это так же просто, как сделать get
запрос.
override suspend fun createPost(post: Post): Response<PostDto> { try { val response = client.post<PostDto> { url("$BASE_URL/posts") contentType(ContentType.Application.Json) setBody(post) } } catch ([...]) { [ same as in the get function ] } }
Мы используем метод post
вместо метода get
. Указываем Content-Type и передаем тело запроса.
Разные примечания
- Убедитесь, что все используемые
data class
s должны быть отмечены аннотацией@kotlinx.serialization.Serializable
- Класс
Response
, используемый в приведенном выше коде, выглядит следующим образом:
sealed class Response<T> { data class Success<T>(val data: T) : Response<T>() data class Error<T>(val message: String) : Response<T>() }
3. Не забудьте добавить разрешения INTERNET
в файл AndroidManifest.
Заключение
Ktor-client очень прост в настройке и очень удобен в использовании. Нет аннотаций для HTTP-методов или частей URL-адресов. Это простой вызов сетевого запроса, который возвращает объект класса данных, с которым нам нужно работать.