HTTP-Запросы
4 мин
Для начала нам стоит разобраться - что такое HTTP-запрос.
Краткое описание технологии
Если коротко, то HTTP-запрос, это сообщение отправленное между клиентом и сервером по протоколу HTTP.
Мы каждый день отправляем тысячи HTTP-запросов переходя по ссылкам в браузере, обновляя страницы сайтов и общаясь в мессенджерах. Основной этого является HTTP (HyperText Transfer Protocol, протокол передачи гипер-текста, подробнее в википедии), позволяющий нам передавать произвольные данные в виде текста по сети. На всякий случай отмечу, что для отправки сообщений и получения ответа нужно два приложения клиент и сервер.
Зафиксируем для себя:
Клиент HTTP - приложение отправляющее запрос.
Сервер HTTP- приложение принимающее запрос и возвращающее на него ответ.
Общая схема действий выглядит так:
1. Клиент отправляет запрос
2. Клиент переходит в режим ожидания ответа
3. Сервер получает запрос
4. Сервер обрабатывает запрос
5. Сервер отправляет ответ обратно
6. Клиент принимает ответ
7. Обмен завершен
К счастью, в большинстве случаев у нас нет нужды глубоко погружаться в детали работы сетевых протоколов так как в большинстве языков программирования уже есть встроенный HTTP-клиент, который можно просто использовать не вдаваясь в суть вещей.
С помощью таких встроенных клиентов мы работаем с HTTP-протоколом не задумываясь о том, как это устроено.
Пример на псевдокоде:
Ресурс = "integration/public_api/employees/"
Соединение = СоздатьСоединениеHTTP(АдресСервера)
Запрос = СоздатьHTTPЗапрос(Ресурс)
Ответ = Соединение.ПолучитьССервера(Запрос )
В этом примере мы видим что мы работаем с какими-то простыми сущностями и объектами языка для получения необходимого результата
Погружение на глубину
А если смотреть вглубь, то нас встретит описание формата общения по HTTP-протоколу.
Посмотрим как выглядит HTTP-запрос для получения главной страницы нашего сайта
GET / HTTP/1.1
User-Agent: PostmanRuntime/7.29.2
Accept: */*
Cache-Control: no-cache
Host: academy.dev-ins.ru
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Именно такой текст отправляется в TCP-порт. Если не сильно вдаваться в суть, TCP - это нижележащая технология, протокол (Transmission Control Protocol, подробнее на википедии), обеспечивающий работу HTTP - протокола.
Как вы видите, наше сообщение это действительно текст, который распознается как HTTP - запрос, благодаря тому что оформлен в специальном виде.
Это сообщение можно разделить условно на две части:
Стартовая строка - GET / HTTP/1.1 - содержит метод HTTP / Протокол / Версию протокола
Заголовки запроса - все остальные строки из этого сообщения в формате Ключ: Значение
Заголовки бывают предопределенные, описанные в стандарте RFC, и произвольные, которые мы можем придумать и использовать самостоятельно.
В сообщении присутствует слово GET, это один из возможных методов (глаголов) HTTP. Указывает на то, что мы хотим получить какую-то информацию с сервера. Так же существуют и другие HTTP-методы (POST, DELETE, PATCH, PUT и т.д.).
После слова GET идет слеш (косая черта), оно указывает на конкретный ресурс к которому мы обращаемся. В данном случае косая черта означает что мы обращаемся к корневому ресурсу.
Ресурсы
Ресурсами называются любые файлы, страницы или обработчики запросов на сервере, к которым можно обратиться из вне. Это исходит из определения аббревиатуры URL (Uniform Resource Locator, Унифицированный указатель ресурса).
Зафиксируем, URL - это указатель на ресурс.
В URL может быть более одной косой черты, например адрес страницы с уроками https://academy.dev-ins.ru/lessons/, стартовая строка запроса к этому URL выглядел бы так
GET /lessons/ HTTP/1.1
как видите, добавилось название ресурса lessons, к которому мы обращаемся и еще одна косая черта.
Параметры URL
Все символы, которые находятся между двумя косыми чертами называются сегментами или параметрами URL, /параметр1/параметр2/.../параметрN
Параметры запроса
Также можно передавать и вспомогательные данные в URL. Для этого необходимо добавить символ вопроса (?) в конец URL и перечислить параметры и их значения разделяя пары ключ - значение символом амперсанд (&). Например, так:
https://academy.dev-ins.ru/lessons?param1=1¶m2=2¶m3=test
Это очень удобно, когда нам нужно передавать какие-то конкретизированные, именованные значения в запросе.
Тело запроса
В URL запроса можно передать далеко не все данные необходимые для работы HTTP-запросов. Чаще всего длина URL имеет ограничения. И если для получения данные с помощью метода GET, этого достаточно, то для метода POST(создание данных на сервер) или PATCH/PUT(обновление данных на сервере) нам уже необходимо какое-то более емкое хранилище. Для этого используется тело запроса (body). Как мог бы выглядеть запрос на добавление
POST /integration/public_api/employees/ HTTP/1.1
Content-Type: application/json
User-Agent: PostmanRuntime/7.29.2
Accept: */*
Cache-Control: no-cache
Host: academy.dev-ins.ru
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 140
{
"first_name": "Иван",
"last_name": "Иванов",
"middle_name": "Иванович",
"email": "ivanov@mail.ru"
}
Как видим, мы отправили POST-запрос, на создание новой записи на сервере, и добавилось несколько важных заголовков:
Content-Type: applcation/json - определяющий формат данных содержащихся в теле
Content-Length: 140 - определяющий размер данных, передающихся в сообщении, в байтах
после заголовков добавляется пустая строка, и дальше идет тело запроса в текстовом виде.
И если Content-Type является по большей части вспомогательным заголовком, от которого зависит только сможет ли какой-то универсальный обработчик автоматически определить тип содержимого или нет, то Content-Length в некоторых случаях может быть критически важен, ведь клиент и сервер должны как-то понять, что они загрузили сообщение полностью и когда количество полученных данных совпадает со значением указанным в заголовке, то передача прекращается.