К статьям

HTTP-Запросы

4 мин


Для начала нам стоит разобраться - что такое HTTP-запрос. 

Краткое описание технологии

Если коротко, то HTTP-запрос, это сообщение отправленное между клиентом и сервером по протоколу HTTP.

Мы каждый день отправляем тысячи HTTP-запросов переходя по ссылкам в браузере, обновляя страницы сайтов и общаясь в мессенджерах. Основной этого является HTTP (HyperText Transfer Protocol, протокол передачи гипер-текста, подробнее в википедии), позволяющий нам передавать произвольные данные в виде текста по сети. На всякий случай отмечу, что для отправки сообщений и получения ответа нужно два приложения клиент и сервер. 

Зафиксируем для себя:
Клиент HTTP - приложение отправляющее запрос.
Сервер HTTP- приложение принимающее запрос и возвращающее на него ответ. 

Общая схема действий выглядит так:

1. Клиент отправляет запрос
2. Клиент переходит в режим ожидания ответа
3. Сервер получает запрос
4. Сервер обрабатывает запрос
5. Сервер отправляет ответ обратно
6. Клиент принимает ответ
7. Обмен завершен

К счастью, в большинстве случаев у нас нет нужды глубоко погружаться в детали работы сетевых протоколов так как в большинстве языков программирования уже есть встроенный HTTP-клиент, который можно просто использовать не вдаваясь в суть вещей.
С помощью таких встроенных клиентов мы работаем с HTTP-протоколом не задумываясь о том, как это устроено.

Пример на псевдокоде:

АдресСервера = "academy.dev-ins.ru"
Ресурс = "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&param2=2&param3=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 в некоторых случаях может быть критически важен, ведь клиент и сервер должны как-то понять, что они загрузили сообщение полностью и когда количество полученных данных совпадает со значением указанным в заголовке, то передача прекращается.
 

Задачи на эту тему: