Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Пример HTTP API HTTP API

HTTP API может быть очень разным и по возможностям, и по внутреннему устройству данных. Подробнее об этом мы поговорим дальше, а сейчас рассмотрим один из популярных вариантов HTTP API.

Обычно HTTP API построен по следующим правилам:

  • Данные передаются в формате JSON
  • Для каждого набора данных используется свой URL

Это далеко не единственный способ организации HTTP API, но один из самых распространенных.

Для примера возьмем сервис DummyJSON, созданный специально для экспериментов с API. Он включает в себя ненастоящие данные, с которыми можно попрактиковаться.

В документации сервиса описываются ресурсы — сущности, информацию о которых мы можем получать по API. Ниже их неполный список:

URL Описание
/posts Список постов
/comments Список комментариев к постам
/users Список пользователей
/todos Список задач

Каждая ссылка, по которой мы получаем какие-то данные в HTTP API, называется эндпоинтом.

Для получения списка пользователей нужно загрузить https://dummyjson.com/users. Ее можно открыть даже в браузере. В ответ вернется такой текст:

{
    "users": [
        {
            "id": 2,
            "firstName": "Sheldon",
            "lastName": "Quigley",
            "maidenName": "Cole",
            "age": 28,
            "gender": "male",
            "email": "hbingley1@plala.or.jp",
            "phone": "+7 813 117 7139",
            "username": "hbingley1",
            "password": "1@#4asdfSDF!WER",
            "birthDate": "2003-08-02",
            "image": "https://robohash.org/doloremquesintcorrupti.png?size=50x50&set=set1",
            "bloodGroup": "O+",
            "height": 187,
            "weight": 74,
            "eyeColor": "Brown",
            "hair": {
            "color": "Blond",
            "type": "Curly"
        },
        {
            ...
        }
    ],
    "total": 100,
    "skip": 0,
    "limit": 30
}

Здесь мы работаем с ненастоящими данными. В реальном API мы бы еще подтвердили доступ, потому что нельзя отдавать такие данные всем подряд. К тому же, в нашем примере выводится пароль — в реальной жизни такого не бывает.

Формат, в котором данные передаются, называется JSON. Давайте остановимся на этом подробнее.

Формат — это способ описания данных. С ним можно работать двумя способами:

  • упаковать данные — то есть сериализовать их
  • извлечь данные — десериализовать их

Задача сериализации и десериализации возникает тогда, когда нам нужно передать данные из программы наружу — например, другим программам.

Данные внутри языков представляются каким-то способом, специфичным для данного языка и даже его конкретной версии. Поэтому для передачи данных и используются универсальные форматы, которые известны всем.

В случае HTTP API этот механизм работает так:

  • Сервис, который предоставляет HTTP API, извлекает данные из хранилища, формирует JSON и отдает его наружу
  • Затем этот JSON может прочитать любая программа с поддержкой JSON (а это большинство современных программ)

Поддержка JSON часто реализована прямо на уровне языков программирования. JSON — это всего лишь текст. У него есть понятная структура, которая прослеживается визуально. Отступы, пробелы и переносы для JSON не имеют значения.

Пример выше может выглядеть и так:

{"users":[{"id":2,"firstName":"Sheldon","lastName":"Quigley","maidenName":"Cole","age":28,"gender":"male","email":"hbingley1@plala.or.jp","phone":"+78131177139","username":"hbingley1","password":"1@#4asdfSDF!WER","birthDate":"2003-08-02","image":"https://robohash.org/doloremquesintcorrupti.png?size=50x50&set=set1","bloodGroup":"O+","height":187,"weight":74,"eyeColor":"Brown","hair":{"color":"Blond","type":"Curly"}}],"total":100,"skip":0,"limit":30}

Разберемся, чем это отличается от передачи данных в HTML.

HTML — обычно служит для передачи данных в браузеры, так как это язык разметки, с помощью которого формируется текст для браузеров. Браузеры считывают HTML и отображают его в виде веб-страницы. HTML не подразумевает работу с данными, которые содержатся внутри него. Теоретически это можно сделать, но на практике будет очень сложно.

JSON — это не единственный формат данных. До него популярным форматом был XML, и сейчас он встречается довольно часто. Так выглядит XML-файл:

<?xml version="1.0"?>
<Recipe>
   <Name>Lime Jello Marshmallow Cottage Cheese Surprise</Name>
   <Description>
     My grandma's favorite (may she rest in peace).
   </Description>
   <Ingredients>
      <Ingredient>
         <Qty unit="box">1</Qty>
         <Item>lime gelatin</Item>
      </Ingredient>
      <Ingredient>
         <Qty unit="g">500</Qty>
         <Item>multicolored tiny marshmallows</Item>
      </Ingredient>
   </Ingredients>
   <Instructions>
      <Step>
         Prepare lime gelatin according to package instructions
      </Step>
      <!-- And so on... -->
   </Instructions>
</Recipe>

XML похож на HTML, но решает другую задачу. XML — это формат данных, как и JSON. Разница лишь в том, что XML не предназначен для вывода.

Структура JSON

Данные в формате JSON хранятся внутри объектов. Объект — это часть данных, ограниченная фигурными скобками, внутри которых задаются ключи и их значения:

{ "id": 3, "hasBranches": true, "name": "Hexlet", "country": "Finland" }

Ключи в JSON всегда обернуты кавычками. В качестве значений могут выступать числа, булевы значения, строки и null:

  • 1, 3, 2.5
  • true, false
  • "one", "two"

Также значениями могут быть массивы:

{ "courses": ["php", "ruby", "python"] }

Причем весь JSON может быть только массивом:

["one", "two", "three"]

Объекты могут быть вложенными в другие объекты:

{ "id": 3, "hasBranches": true, "name": "Hexlet", "address": { "country": "Finland", "city": "Helsinki" } }

А еще объекты можно вложить в массивы:

{ "courses": [{ "id": 1, "name": "php" }, { "id": 2, "name": "javascript" }] }

Метаданные

Если посмотреть на структуру ответа /users, то становится видно, что список пользователей передается как массив внутри объекта с дополнительными параметрами:

{
    "users": [],
    "total": 100,
    "skip": 0,
    "limit": 30
}

Зачем так сделано? Почему бы сразу не отдавать массив пользователей?

[{ ... }, { ... }]

Ответ здесь очень простой. Часто нужно передавать не только данные, но и метаданные — то есть данные о данных. Например, к метаданным относится общее количество пользователей. Если бы у нас был массив, то эту информацию было бы невозможно добавить без изменения структуры и перехода от массива к объекту.

Объект же позволяет добавлять новые данные, сохраняя обратную совместимость в структуре, не ломая ее. Нужно просто добавить новый ключ на верхний уровень, и все готово.

Пагинация

Иногда данных слишком много: как на Хекслете, у которого сотни тысяч пользователей. JSON с таким объемом данных получится огромным и тяжелым.

Для решения этой задачи используют пагинацию — с ней данные отдаются не целиком, а небольшими наборами. Пагинацию мы встречаем в интернете на каждом шагу. Вспомните результаты поиска в Google — поисковик находит миллионы страниц, но показываются только первые десять результатов, а остальные скрывает на других страницах.

В API, с которым мы работаем, по умолчанию отдается 30 результатов. Это видно из возвращаемого JSON:

{
    "users": [],
    "total": 100,
    "skip": 0,
    "limit": 30
}

Как в таком случае получить вторые 30 человек? Нужно добавить параметр skip: https://dummyjson.com/users?skip=30. Так будет выглядеть JSON:

{
    "users": [],
    "total": 100,
    "skip": "30",
    "limit": 30
}

Ограничение данных

Представим, что нам нужны не все данные, а только их часть. Для этого в нашем HTTP API есть параметр запроса select: https://dummyjson.com/users?select=firstName,gender. Так он выглядит:

{
     "users": [
        {
            "id": 1,
            "firstName": "Terry",
            "gender": "male"
        },
        {
            "id": 2,
            "firstName": "Sheldon",
            "gender": "male"
        },
        {
            "id": 3,
            "firstName": "Terrill",
            "gender": "male"
        }
    ]
}

Одиночный ресурс

Эндпоинт /users возвращает список пользователей. Если нам нужен один пользователь, то для этого понадобится другой эндпоинт — /users/{id}.

Этот эндпоинт называется динамическим, потому что у него есть меняющаяся часть. Вместо {id} подставляется идентификатор конкретного пользователя, данные которого мы хотим получить.

Возьмем для примера https://dummyjson.com/users/9 и посмотрим на результат:

{
    "id": 9,
    "firstName": "Demetrius",
    "lastName": "Corkery",
    "maidenName": "Gleason",
    "age": 22,
    "gender": "male",
    "email": "nloiterton8@aol.com",
    "phone": "+86 356 590 9727",
    "username": "nloiterton8",
    "password": "HTQxxXV9Bq4",
    "birthDate": "1971-03-11",
    "image": "https://robohash.org/excepturiiuremolestiae.png?size=50x50&set=set1",
    "bloodGroup": "A+",
    "height": 170,
    "weight": 97.1,
    "eyeColor": "Green",
    ...
}

Вложенные ресурсы

Часто пользователи могут писать посты на сайте. Если мы захотим увидеть весь список постов, то используем эндпоинт /posts.

Чтобы увидеть посты конкретного пользователя, мы воспользуемся вложенными ресурсами: https://dummyjson.com/users/3/posts.

Этот эндпоинт вернет все посты пользователя с идентификатором 3:

{
    "posts": [
        {
            "id": 58,
            "title": "Balloons are pretty and come in different colors",
            "body": "Balloons are pretty and come in different colors, different shapes, different sizes, and they can even adjust sizes as needed. But don't make them too big or they might just pop, and then bye-bye balloon. It'll be gone and lost for the rest of mankind. They can serve a variety of purposes, from decorating to water balloon wars. You just have to use your head to think a little bit about what to do with them.",
            "userId": 3,
            "tags": [
                "american",
                "crime",
                "magical"
            ],
            "reactions": 9727
        },
    ],
    "total": 4,
    "skip": 0,
    "limit": 4
}

По такому же принципу устроена работа со всеми остальными ресурсами:

URL Описание
/users/{id}/posts Список постов пользователя
/users/{id}/comments Список комментариев пользователя
/users/{id}/todos Список задач пользователя

Выводы

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


Самостоятельная работа

Приложения для управления задачами очень популярны. Не исключено, что в будущем вы будете работать с API одного из таких приложений. Потренируемся работать с ними:

  • Подключитесь к DummyJSON с помощью команды:

openssl s_client -connect dummyjson.com:443
  • Выполните запрос на получение списка Todos. Введите строку запроса и заголовок host, так же как при подключении с помощью telnet

  • Выполните новый запрос с добавлением параметров «Пропуск» и «Лимит»

При успешном выполнении запросов вы получите HTTP-ответ с JSON.

Если DummyJSON не работает, попробуйте подключиться к https://jsonplaceholder.typicode.com/todos


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 6 300 ₽ в месяц
Разработка фронтенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 25 апреля
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Django
10 месяцев
с нуля
Старт 25 апреля
профессия
от 6 183 ₽ в месяц
Ручное тестирование веб-приложений
4 месяца
с нуля
Старт 25 апреля
профессия
от 6 300 ₽ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 25 апреля
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Laravel
10 месяцев
с нуля
Старт 25 апреля
профессия
от 9 900 ₽ в месяц
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
16 месяцев
с нуля
Старт 25 апреля
профессия
от 6 300 ₽ в месяц
Разработка бэкенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 25 апреля
профессия
новый
Автоматизированное тестирование веб-приложений на JavaScript
8 месяцев
c опытом
в разработке
Старт 25 апреля

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»