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

Пример HTTP API HTTP API

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

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

Это далеко не единственный способ организации HTTP API, но один из самых распространенных. Для примера возьмем сервис https://dummyjson.com/, созданный специально для экспериментов с 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 c нас бы еще потребовали подтвердить доступ, так как кому угодно отдавать такие данные нельзя. К тому же, здесь выводится пароль, чего в реальной жизни тоже не бывает.

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

В случае 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 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, он не предназначен для вывода.

Структура 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, где в результате находятся миллионы страниц, но показываются только первые 10, а остальное скрыто за другими страницами.

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

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

Как в таком случае получить вторые 30 человек? Добавив параметр skip: https://dummyjson.com/users?skip=30

{
    "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 одного из таких приложений.

  1. С помощью telnet выполните запрос на получение списка Todos

  2. Выполните новый запрос с добавлением параметров, таких как пропуск и лимит

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


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

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

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

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

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

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

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

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

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

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

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
с нуля
Разработка фронтенд-компонентов для веб-приложений
1 декабря 10 месяцев
Иконка программы Онлайн-буткемп. Фронтенд-разработчик
Профессия
Новый с нуля
Интенсивное обучение профессии в режиме полного дня
15 декабря 4 месяца
Иконка программы Python-разработчик
Профессия
с нуля
Разработка веб-приложений на Django
1 декабря 10 месяцев
Иконка программы Java-разработчик
Профессия
с нуля
Разработка приложений на языке Java
1 декабря 10 месяцев
Иконка программы PHP-разработчик
Профессия
с нуля
Разработка веб-приложений на Laravel
1 декабря 10 месяцев
Иконка программы Инженер по тестированию
Профессия
с нуля
Ручное тестирование веб-приложений
дата определяется 4 месяца
Иконка программы Node.js-разработчик
Профессия
с нуля
Разработка бэкенд-компонентов для веб-приложений
1 декабря 10 месяцев
Иконка программы Fullstack-разработчик
Профессия
с нуля
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
1 декабря 16 месяцев

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

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

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

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