[содержание](/readme.md) # Http запросы В Kotlin-е есть встроенные функции работы с http-запросами, но стандартный код для сетевых запросов сложен, излишен и в реальном мире почти не используется. Используются библиотеки. Самые популярные: OkHttp, Fuel и Retrofit. Мы рассмотрим работу с http на примере библиотеки [Fuel](https://github.com/kittinunf/fuel). ## Установка библиотеки 1. В зависимости приложения добавляем (что такое зависимости и куда их добавлять мы рассмотрим в теме про работу с IDE): ``` implementation 'com.github.kittinunf.fuel:fuel-android:2.2.1' ``` > актуальную версию библиотеки уточняйте на сайте разработчика 2. В секцию импорта добавить ``import com.github.kittinunf.result.Result``. ## Примеры запросов Запросы бывают двух типов: синхронные (приложение ждет ответа от сервера, останавливая работу) и асинхронные (запрос посылается в фоне, выполнение программы продолжается - такой режим предпочтительнее, т.к. не "замораживает" интерфейс). Но мы с вами уже знаем, что существуют корутины и мы любой синхронный код можем запустить асинхронно, поэтому дальше будем рассматривать синхронный код. Запрос можно сформировать через фабричные методы класса Fuel: ```kt Fuel.get(...) Fuel.post(...) // полный список доступных методов см. на сайте библиотеки, нам достаточно этих двух ``` Или через расширение объекта String: ```kt "http://адрес.сайта".httpGet() "http://адрес.сайта".httpPost() ``` Далее рассматривается авторизация на тестовом сервисе: > Вариантов авторизации существует множество, далее рассмотрен вариант, который использовался в демо-экзамене на курсах "Мастера 5000" **Алгоритм авторизации**: * при любом запросе (кроме login и logout) должен добавляться параметр token если токен не найден, то вернется сообщение, что пользователь не авторизован: ```json {"notice":{"answer": "user not authorized"}} ``` * для получения токена необходимо послать **post** запрос на URL */login* с параметрами login и password (в качестве логина используйте *ИФамилия* в латинской транскрипции, т.е. Евгений колесников = EKolesnikov. Пароль любой) * если токен уже был получен, то сервер вернет ошибку ```json {"notice":{"answer": "User is active"}} ``` в этом случае нужно разлогиниться (послать запрос с теми же параметрами на URL */logout*) * при успешной авторизации сервер вернет токен: ```json {"notice": {"token":123} ``` > Адрес тестового сервера уточняйте в начале работы ```kt import com.github.kittinunf.fuel.Fuel import com.github.kittinunf.result.Result fun main() { // здесь УРЛ другого сервиса, при тестировании авторизации вставляйте свой val URL = "https://httpbin.org" val (_, _, result) = Fuel .post( "$URL/post", // путь тоже должен быть другой listOf( "login" to "EKolesnikov", // в массиве передаются параметры запроса "password" to "123456")) .responseString() // разбираем результат when (result) { is Result.Failure -> { // на ошибку лучше выбросить исключение println( result.getException().toString() ) } is Result.Success -> { // тут реализуете разбор полученного ответа println( result.get() ) } } } ``` На этот запрос придет примерно такой ответ: ```json { "args": {}, "data": "", "files": {}, "form": { "login": "EKolesnikov", "password": "123456" }, "headers": { "Accept": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2", "Content-Length": "33", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.org", "User-Agent": "Java/11.0.5", "X-Amzn-Trace-Id": "Root=1-5e3d990d-f0d25f92f87cec3612db9f75" }, "json": null, "origin": "888.888.888.888", "url": "https://httpbin.org/post" } ``` Тут, как и в ответе сервиса, данные в формате JSON. ## JSON JSON (JavaScript Object Notation) - простой формат обмена данными, удобный для чтения и написания как человеком, так и компьютером. JSON - текстовый формат, полностью независимый от языка реализации. JSON основан на двух структурах данных: * Коллекция пар ключ/значение. В разных языках, эта концепция реализована как объект, запись, структура, словарь, хэш, именованный список или ассоциативный массив. ```json "login":"EKolesnikov" ``` * Упорядоченный список значений. В большинстве языков это реализовано как массив, вектор, список или последовательность. ```json [1,2,3] ``` Это универсальные структуры данных. Почти все современные языки программирования поддерживают их в какой-либо форме. Логично предположить, что формат данных, независимый от языка программирования, должен быть основан на этих структурах. Подробное описание можете посмотреть в интернете, для нас достаточно знание следующих типов: * *"литерал"* - в двойных кавычках строка в формате UTF-8, строка может быть как ключем, так и значением: ```json "login":"EKolesnikov" ``` * *{объект}* - неупорядоченный набор пар ключ:значение, причем значением может быть любой другой тип. Пары разделяются запятыми: ```json {"login":"EKolesnikov", "value": 1, "object": {...}, "array": [...]} ``` * *[массив]* - упорядоченная коллекция значений. Значения разделены запятой. Значением может быть любой другой тип. ```json ["login", 1, {...}, [...], null, true] ``` * *числа* - числа пишутся без кавычек, могут быть как ключем (не уверен - проверить), так и значением. Дробная часть обозначается точкой: ```json "int": 123, "float": 12.34 ``` * логические константы и null: ```json true, false, null ``` Для работы с JSON в котлине есть типы JSON [содержание](/readme.md)