HTML Diff
1 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>HTTP API может быть очень разным и по возможностям, и по внутреннему устройству данных. Подробнее об этом мы поговорим дальше, а сейчас рассмотрим один из популярных вариантов HTTP API.</p>
1 <p>HTTP API может быть очень разным и по возможностям, и по внутреннему устройству данных. Подробнее об этом мы поговорим дальше, а сейчас рассмотрим один из популярных вариантов HTTP API.</p>
2 <p>Обычно HTTP API построен по следующим правилам:</p>
2 <p>Обычно HTTP API построен по следующим правилам:</p>
3 <ul><li>Данные передаются в формате JSON</li>
3 <ul><li>Данные передаются в формате JSON</li>
4 <li>Для каждого набора данных используется свой URL</li>
4 <li>Для каждого набора данных используется свой URL</li>
5 </ul><p>Это далеко не единственный способ организации HTTP API, но один из самых распространенных.</p>
5 </ul><p>Это далеко не единственный способ организации HTTP API, но один из самых распространенных.</p>
6 <p>Для примера возьмем сервис<a>HTTP Server</a>, созданный специально для экспериментов с API. Он включает в себя ненастоящие данные, с которыми можно попрактиковаться.</p>
6 <p>Для примера возьмем сервис<a>HTTP Server</a>, созданный специально для экспериментов с API. Он включает в себя ненастоящие данные, с которыми можно попрактиковаться.</p>
7 <p>В документации сервиса описываются<strong>ресурсы</strong>- сущности, информацию о которых мы можем получать по API. Ниже их неполный список:</p>
7 <p>В документации сервиса описываются<strong>ресурсы</strong>- сущности, информацию о которых мы можем получать по API. Ниже их неполный список:</p>
8 <p>Каждая ссылка, по которой мы получаем какие-то данные в HTTP API, называется<strong>эндпоинтом</strong>.</p>
8 <p>Каждая ссылка, по которой мы получаем какие-то данные в HTTP API, называется<strong>эндпоинтом</strong>.</p>
9 <p>Для получения списка пользователей нужно загрузить<a>https://http.hexlet.app/http-api/users</a>. Ее можно открыть даже в браузере. В ответ вернется такой текст:</p>
9 <p>Для получения списка пользователей нужно загрузить<a>https://http.hexlet.app/http-api/users</a>. Ее можно открыть даже в браузере. В ответ вернется такой текст:</p>
10 <p>Здесь мы работаем с ненастоящими данными. В реальном API мы бы еще подтвердили доступ, потому что нельзя отдавать такие данные всем подряд.</p>
10 <p>Здесь мы работаем с ненастоящими данными. В реальном API мы бы еще подтвердили доступ, потому что нельзя отдавать такие данные всем подряд.</p>
11 <p>Формат, в котором данные передаются, называется<strong>JSON</strong>. Давайте остановимся на этом подробнее.</p>
11 <p>Формат, в котором данные передаются, называется<strong>JSON</strong>. Давайте остановимся на этом подробнее.</p>
12 <p><strong>Формат</strong>- это способ описания данных. С ним можно работать двумя способами:</p>
12 <p><strong>Формат</strong>- это способ описания данных. С ним можно работать двумя способами:</p>
13 <ul><li>упаковать данные - то есть сериализовать их</li>
13 <ul><li>упаковать данные - то есть сериализовать их</li>
14 <li>извлечь данные - десериализовать их</li>
14 <li>извлечь данные - десериализовать их</li>
15 </ul><p>Задача сериализации и десериализации возникает тогда, когда нам нужно передать данные из программы наружу - например, другим программам.</p>
15 </ul><p>Задача сериализации и десериализации возникает тогда, когда нам нужно передать данные из программы наружу - например, другим программам.</p>
16 <p>Данные внутри языков представляются каким-то способом, специфичным для данного языка и даже его конкретной версии. Поэтому для передачи данных и используются универсальные форматы, которые известны всем.</p>
16 <p>Данные внутри языков представляются каким-то способом, специфичным для данного языка и даже его конкретной версии. Поэтому для передачи данных и используются универсальные форматы, которые известны всем.</p>
17 <p>В случае HTTP API этот механизм работает так:</p>
17 <p>В случае HTTP API этот механизм работает так:</p>
18 <ul><li>Сервис, который предоставляет HTTP API, извлекает данные из хранилища, формирует JSON и отдает его наружу</li>
18 <ul><li>Сервис, который предоставляет HTTP API, извлекает данные из хранилища, формирует JSON и отдает его наружу</li>
19 <li>Затем этот JSON может прочитать любая программа с поддержкой JSON (а это большинство современных программ)</li>
19 <li>Затем этот JSON может прочитать любая программа с поддержкой JSON (а это большинство современных программ)</li>
20 </ul><p>Поддержка JSON часто реализована прямо на уровне языков программирования. JSON - это всего лишь текст. У него есть понятная структура, которая прослеживается визуально. Отступы, пробелы и переносы для JSON не имеют значения.</p>
20 </ul><p>Поддержка JSON часто реализована прямо на уровне языков программирования. JSON - это всего лишь текст. У него есть понятная структура, которая прослеживается визуально. Отступы, пробелы и переносы для JSON не имеют значения.</p>
21 <p>Пример выше может выглядеть и так:</p>
21 <p>Пример выше может выглядеть и так:</p>
22 <p>Разберемся, чем это отличается от передачи данных в HTML.</p>
22 <p>Разберемся, чем это отличается от передачи данных в HTML.</p>
23 <p>HTML - обычно служит для передачи данных в браузеры, так как это язык разметки, с помощью которого формируется текст для браузеров. Браузеры считывают HTML и отображают его в виде веб-страницы. HTML не подразумевает работу с данными, которые содержатся внутри него. Теоретически это можно сделать, но на практике будет очень сложно.</p>
23 <p>HTML - обычно служит для передачи данных в браузеры, так как это язык разметки, с помощью которого формируется текст для браузеров. Браузеры считывают HTML и отображают его в виде веб-страницы. HTML не подразумевает работу с данными, которые содержатся внутри него. Теоретически это можно сделать, но на практике будет очень сложно.</p>
24 <p>JSON - это не единственный формат данных. До него популярным форматом был XML, и сейчас он встречается довольно часто. Так выглядит XML-файл:</p>
24 <p>JSON - это не единственный формат данных. До него популярным форматом был XML, и сейчас он встречается довольно часто. Так выглядит XML-файл:</p>
25 <p>XML похож на HTML, но решает другую задачу. XML - это формат данных, как и JSON. Разница лишь в том, что XML не предназначен для вывода.</p>
25 <p>XML похож на HTML, но решает другую задачу. XML - это формат данных, как и JSON. Разница лишь в том, что XML не предназначен для вывода.</p>
26 <h2>Структура JSON</h2>
26 <h2>Структура JSON</h2>
27 <p>Данные в формате JSON хранятся внутри объектов.<strong>Объект</strong>- это часть данных, ограниченная фигурными скобками, внутри которых задаются ключи и их значения:</p>
27 <p>Данные в формате JSON хранятся внутри объектов.<strong>Объект</strong>- это часть данных, ограниченная фигурными скобками, внутри которых задаются ключи и их значения:</p>
28 <p>Ключи в JSON всегда обернуты кавычками. В качестве значений могут выступать числа, булевы значения, строки и null:</p>
28 <p>Ключи в JSON всегда обернуты кавычками. В качестве значений могут выступать числа, булевы значения, строки и null:</p>
29 <ul><li>1, 3, 2.5</li>
29 <ul><li>1, 3, 2.5</li>
30 <li>true, false</li>
30 <li>true, false</li>
31 <li>"one", "two"</li>
31 <li>"one", "two"</li>
32 </ul><p>Также значениями могут быть массивы:</p>
32 </ul><p>Также значениями могут быть массивы:</p>
33 <p>Причем весь JSON может быть только массивом:</p>
33 <p>Причем весь JSON может быть только массивом:</p>
34 <p>Объекты могут быть вложенными в другие объекты:</p>
34 <p>Объекты могут быть вложенными в другие объекты:</p>
35 <p>А еще объекты можно вложить в массивы:</p>
35 <p>А еще объекты можно вложить в массивы:</p>
 
36 + <h2>Метаданные</h2>
36 <p>Если посмотреть на структуру ответа<em>/users</em>, то становится видно, что список пользователей передается как массив внутри объекта с дополнительными параметрами:</p>
37 <p>Если посмотреть на структуру ответа<em>/users</em>, то становится видно, что список пользователей передается как массив внутри объекта с дополнительными параметрами:</p>
37 <p>Зачем так сделано? Почему бы сразу не отдавать массив пользователей?</p>
38 <p>Зачем так сделано? Почему бы сразу не отдавать массив пользователей?</p>
38 <p>Ответ здесь очень простой. Часто нужно передавать не только данные, но и<strong>метаданные</strong>- то есть данные о данных. Например, к метаданным относится общее количество пользователей. Если бы у нас был массив, то эту информацию было бы невозможно добавить без изменения структуры и перехода от массива к объекту.</p>
39 <p>Ответ здесь очень простой. Часто нужно передавать не только данные, но и<strong>метаданные</strong>- то есть данные о данных. Например, к метаданным относится общее количество пользователей. Если бы у нас был массив, то эту информацию было бы невозможно добавить без изменения структуры и перехода от массива к объекту.</p>
39 <p>Объект же позволяет добавлять новые данные, сохраняя обратную совместимость в структуре, не ломая ее. Нужно просто добавить новый ключ на верхний уровень, и все готово.</p>
40 <p>Объект же позволяет добавлять новые данные, сохраняя обратную совместимость в структуре, не ломая ее. Нужно просто добавить новый ключ на верхний уровень, и все готово.</p>
40 <h2>Пагинация</h2>
41 <h2>Пагинация</h2>
41 <p>Иногда данных слишком много: как на Хекслете, у которого сотни тысяч пользователей. JSON с таким объемом данных получится огромным и тяжелым.</p>
42 <p>Иногда данных слишком много: как на Хекслете, у которого сотни тысяч пользователей. JSON с таким объемом данных получится огромным и тяжелым.</p>
42 <p>Для решения этой задачи используют<strong>пагинацию</strong>- с ней данные отдаются не целиком, а небольшими наборами. Пагинацию мы встречаем в интернете на каждом шагу. Вспомните результаты поиска в Google - поисковик находит миллионы страниц, но показываются только первые десять результатов, а остальные скрывает на других страницах.</p>
43 <p>Для решения этой задачи используют<strong>пагинацию</strong>- с ней данные отдаются не целиком, а небольшими наборами. Пагинацию мы встречаем в интернете на каждом шагу. Вспомните результаты поиска в Google - поисковик находит миллионы страниц, но показываются только первые десять результатов, а остальные скрывает на других страницах.</p>
43 <p>В API, с которым мы работаем, по умолчанию отдается 30 результатов. Это видно из возвращаемого JSON:</p>
44 <p>В API, с которым мы работаем, по умолчанию отдается 30 результатов. Это видно из возвращаемого JSON:</p>
44 <p>Как в таком случае получить вторые 30 человек? Нужно добавить параметр<em>skip</em>:<a>https://http.hexlet.app/http-api/users?skip=30</a>. Так будет выглядеть JSON:</p>
45 <p>Как в таком случае получить вторые 30 человек? Нужно добавить параметр<em>skip</em>:<a>https://http.hexlet.app/http-api/users?skip=30</a>. Так будет выглядеть JSON:</p>
45 <p>В примере с пользователями это не имеет смысла, так как пользователей всего 10. Но, например, для запроса постов полезно, так как их количество может быть больше<a>https://http.hexlet.app/http-api/posts?skip=30</a>:</p>
46 <p>В примере с пользователями это не имеет смысла, так как пользователей всего 10. Но, например, для запроса постов полезно, так как их количество может быть больше<a>https://http.hexlet.app/http-api/posts?skip=30</a>:</p>
46 <h2>Ограничение данных</h2>
47 <h2>Ограничение данных</h2>
47 <p>Представим, что нам нужны не все данные, а только их часть. Для этого в нашем HTTP API есть параметр запроса<em>select</em>:<a>https://http.hexlet.app/http-api/users?select=firstName,email</a>. Так он выглядит:</p>
48 <p>Представим, что нам нужны не все данные, а только их часть. Для этого в нашем HTTP API есть параметр запроса<em>select</em>:<a>https://http.hexlet.app/http-api/users?select=firstName,email</a>. Так он выглядит:</p>
48 <h2>Одиночный ресурс</h2>
49 <h2>Одиночный ресурс</h2>
49 <p>Эндпоинт<em>/users</em>возвращает список пользователей. Если нам нужен один пользователь, то для этого понадобится другой эндпоинт -<em>/users/</em></p>
50 <p>Эндпоинт<em>/users</em>возвращает список пользователей. Если нам нужен один пользователь, то для этого понадобится другой эндпоинт -<em>/users/</em></p>
50 <p>.</p>
51 <p>.</p>
51 <p>Этот эндпоинт называется<strong>динамическим</strong>, потому что у него есть меняющаяся часть. Вместо<em></em></p>
52 <p>Этот эндпоинт называется<strong>динамическим</strong>, потому что у него есть меняющаяся часть. Вместо<em></em></p>
52 <p>подставляется идентификатор конкретного пользователя, данные которого мы хотим получить.</p>
53 <p>подставляется идентификатор конкретного пользователя, данные которого мы хотим получить.</p>
53 <p>Возьмем для примера<a>https://http.hexlet.app/http-api/users/1</a>и посмотрим на результат:</p>
54 <p>Возьмем для примера<a>https://http.hexlet.app/http-api/users/1</a>и посмотрим на результат:</p>
54 <h2>Вложенные ресурсы</h2>
55 <h2>Вложенные ресурсы</h2>
55 <p>Часто пользователи могут писать посты на сайте. Если мы захотим увидеть весь список постов, то используем эндпоинт<em>/posts</em>.</p>
56 <p>Часто пользователи могут писать посты на сайте. Если мы захотим увидеть весь список постов, то используем эндпоинт<em>/posts</em>.</p>
56 <p>Чтобы увидеть посты конкретного пользователя, мы воспользуемся вложенными ресурсами:<a>https://http.hexlet.app/http-api/users/1/posts</a>.</p>
57 <p>Чтобы увидеть посты конкретного пользователя, мы воспользуемся вложенными ресурсами:<a>https://http.hexlet.app/http-api/users/1/posts</a>.</p>
57 <p>Этот эндпоинт вернет все посты пользователя с идентификатором 1:</p>
58 <p>Этот эндпоинт вернет все посты пользователя с идентификатором 1:</p>
58 <p>По такому же принципу устроена работа со всеми остальными ресурсами:</p>
59 <p>По такому же принципу устроена работа со всеми остальными ресурсами:</p>
59 <h2>Выводы</h2>
60 <h2>Выводы</h2>
60 <p>Мы разобрали одно конкретное HTTP API, которое имеет свои правила по взаимодействию с эндпоинтами. В других HTTP API все будет по-другому - здесь каждый разработчик решает сам. Неизменным остается то, что мы работаем через HTTP и используем его возможности.</p>
61 <p>Мы разобрали одно конкретное HTTP API, которое имеет свои правила по взаимодействию с эндпоинтами. В других HTTP API все будет по-другому - здесь каждый разработчик решает сам. Неизменным остается то, что мы работаем через HTTP и используем его возможности.</p>