Программирование и IT
Что такое API
API — это условленный способ одной программы попросить что-то у другой. Никакого экрана и кнопок: запрос уходит текстом по сети, ответ приходит в машиночитаемом виде. Разобравшись с четырьмя частями HTTP-запроса, ты сможешь читать документацию любого сервиса.
В этой статье
Договор между программами#
Application Programming Interface — это список операций, которые одна программа
согласилась выполнять по просьбе другой, вместе с правилами: как просьбу
оформить, что придёт в ответ, что считается ошибкой.
Сравнение с окном выдачи работает лучше метафор про официанта. Ты не заходишь
на склад и не роешься в базе данных сервиса — ты подаёшь бумагу установленной
формы в окно и получаешь ответ установленной формы. Что происходит внутри, тебя
не касается; важно, что форма не меняется без предупреждения.
Из этого вытекает главная польза. Погодный сайт не измеряет температуру сам —
он спрашивает у метеослужбы. Магазин не считает стоимость доставки — он
спрашивает у перевозчика. Приложение банка не хранит карту города — оно берёт
её у картографического сервиса. Каждый делает своё, обмен идёт по описанному
интерфейсу.
Слово «API» употребляют шире, чем про сеть: у библиотеки внутри языка
программирования тоже есть API — набор её функций. Но когда в вакансии или
статье пишут «работа с API» без уточнений, почти всегда имеют в виду
веб-интерфейс поверх HTTP. О нём дальше и речь.
Из чего состоит запрос#
У HTTP-запроса четыре части.
- Метод — что именно ты хочешь сделать.
- Адрес — над чем:
https://api.example.com/users/42. - Заголовки — служебные пометки: формат данных, ключ доступа, язык.
- Тело — сами данные; у запросов на чтение его нет.
Ответ устроен зеркально: код состояния, заголовки и тело.
Адреса в аккуратно сделанном сервисе строятся по одной схеме: существительное
во множественном числе — это коллекция, к нему через дробь идентификатор — это
один объект. /orders — все заказы, /orders/1207 — один заказ,
/orders/1207/items — его состав.
Методы#
| Метод | Смысл | Меняет данные |
|---|---|---|
GET |
получить объект или список | нет |
POST |
создать новый объект | да |
PUT |
заменить объект целиком | да |
PATCH |
изменить часть полей | да |
DELETE |
удалить объект | да |
GET называют безопасным методом: по стандарту он не должен ничего менять на
сервере, поэтому браузеры и промежуточные узлы спокойно его повторяют и
кешируют. PUT и DELETE идемпотентны — десять одинаковых вызовов дают тот же
результат, что один. А вот POST не идемпотентен: два нажатия «оплатить»
создадут два платежа, и защита от этого — забота разработчика.
Коды ответов#
Первая цифра кода задаёт смысл целиком: 2 — получилось, 3 — ищи в другом
месте, 4 — ошибка на стороне того, кто спрашивал, 5 — сломалось на сервере.
| Код | Значение | Что делать |
|---|---|---|
| 200 | OK, ответ в теле | читать данные |
| 201 | объект создан | забрать адрес нового объекта |
| 204 | выполнено, тела нет | ничего не разбирать |
| 301, 302 | адрес переехал | пойти по адресу из заголовка Location |
| 400 | запрос неверно составлен | искать опечатку в теле или параметрах |
| 401 | ты не представился | передать ключ или токен |
| 403 | представились, но прав нет | проверить права учётной записи |
| 404 | объекта нет | проверить адрес и идентификатор |
| 409 | конфликт с текущим состоянием | перечитать объект и повторить |
| 422 | данные не проходят проверку | читать текст ошибки в теле |
| 429 | слишком часто | подождать и снизить темп |
| 500 | сбой на сервере | повторить позже, при повторе — писать в поддержку |
| 502, 503 | сервис недоступен | повторить с нарастающей паузой |
Пара 401 и 403 путается чаще всего. 401 означает «я не знаю, кто ты» —
заголовок с ключом отсутствует, просрочен или неверен. 403 — «я знаю, кто ты,
и тебе сюда нельзя»: подставлять другой ключ бессмысленно, нужны права.
JSON#
Данные почти всегда передают в JSON — текстовом формате, который одинаково
читают человек и машина.
Правил немного: ключи — всегда в двойных кавычках, строки — тоже, числа и
true, false, null — без кавычек, запятая после последнего элемента
запрещена. Вложенность произвольная: значением может быть объект или массив.
Самая частая ошибка новичка — одинарные кавычки: {'id': 1207} не JSON, а
синтаксис Python. Вторая — лишняя запятая перед закрывающей скобкой. И то и
другое сервер встретит кодом 400.
Заголовок Content-Type: application/json сообщает серверу, что в теле именно
JSON. Без него многие сервисы попробуют прочитать тело как данные формы и
откажут.
Ключи доступа#
Открытых интерфейсов, работающих без опознания, мало. Обычно сервис выдаёт
ключ, а ты прикладываешь его к каждому запросу.
- Токен в заголовке — распространённый вариант:
Authorization: Bearer ТОКЕН. - Ключ в отдельном заголовке — например
X-Api-Key: ТОКЕН. - Ключ параметром адреса — встречается в старых сервисах; способ плохой:
адрес целиком попадает в журналы серверов и в историю браузера.
Три правила обращения с ключом: не коммитить его в репозиторий (для этого есть
переменные окружения и файл, исключённый из индекса), не отдавать на страницу,
которую видит браузер, и перевыпускать при малейшем подозрении. Утёкший ключ —
это чужие запросы от твоего имени и твой счёт за них.
Отдельно живут ограничения по частоте: сервис разрешает, скажем, шестьдесят
запросов в минуту, а сверх этого отвечает 429. Правильная реакция — пауза с
удвоением: подождать секунду, потом две, потом четыре.
Первый запрос через curl#
curl есть почти в любой системе и делает ровно то, что написано в строке, —
поэтому им удобно проверять документацию до написания кода.
Самый простой вызов — чтение. Первая строка напечатает тело ответа, вторая
добавит к нему строку состояния и заголовки, третья пройдёт переадресацию и
сохранит результат в файл:
Создание объекта требует трёх добавок: метода, заголовка с типом данных и
тела.
Ключ -d сам по себе включает метод POST, поэтому -X POST рядом с ним
можно опустить. Длинный JSON в терминале неудобен — положи его в файл и
сошлись: -d @body.json.
Ключ передают заголовком, а само значение берут из переменной окружения, чтобы
оно не осело в истории команд:
Чтобы разглядеть ответ, его пропускают через форматирование: curl … | jq .
раскрасит и расставит отступы. Другие приёмы работы с выводом терминала — в
разборе команд Linux.
Как читать чужую документацию#
Порядок чтения всегда один. Сначала — раздел про опознание: где взять ключ и в
каком заголовке его передавать. Затем — базовый адрес, к которому дописываются
пути. Затем — одна конкретная операция, которая тебе нужна: метод, путь,
обязательные параметры, пример ответа. И только потом всё остальное.
Хорошая документация даёт готовую строку curl для каждой операции — с неё и
начинай, подставив свой ключ. Если строки нет, собери её сам по таблице
параметров: работающий вызов в терминале избавляет от догадок, почему не
работает код.
Полезно знать про два соседних формата описания. OpenAPI — машиночитаемое
описание интерфейса, из которого генерируются страницы документации и клиенты
на разных языках. GraphQL — другой подход, где адрес один, а что именно вернуть,
клиент описывает в теле запроса.
Частые ошибки#
Забытый заголовок с типом данных. Тело — JSON, а сервер этого не знает:
ответ 400 или 415.
Косая черта в конце пути. Для части сервисов /users и /users/ — разные
адреса; один отвечает, другой переадресует или отдаёт 404.
Разбор ответа без проверки кода. Программа читает тело, не посмотрев на
код состояния, и падает на разборе страницы с ошибкой. Сначала код, потом
данные.
Ключ в исходниках. Проверь историю репозитория до первой публикации:
удалить из текущей версии недостаточно.
Учебный сервис, к которому не жалко слать любые запросы, проще всего поднять
в контейнере — как это делается, описано в статье
что такое Docker.
План по этапам
- Прочитать ответ вручнуюСделать GET к открытому сервису через curl -i и назвать все четыре части ответа.
- Разобрать JSONВзять ответ и вытащить из него три поля, в том числе вложенное и элемент массива.
- Запрос с теломОтправить POST с заголовком Content-Type и телом JSON, сверить код ответа с документацией.
- ОпознаниеПолучить ключ у любого бесплатного сервиса, передать его заголовком и убедиться, что без ключа приходит 401.
- Обработка ошибокНаписать программу, которая проверяет код ответа и повторяет запрос с паузой при 429 и 503.
Начать изучать эту тему у себя
План ляжет в твой репозиторий: отмечай этапы, веди конспект — история изменений покажет, как ты продвинулся.
Проверь себя
1.Какой код ответа HTTP означает «объект не найден»?
2.Какой код ответа сервер возвращает, когда объект успешно создан?
3.Какой метод HTTP по стандарту не должен изменять данные на сервере?
4.Что означает код 401?
Источники
-
HTTP на MDNМетоды, коды ответов и заголовки с пояснением каждого, на русскомбесплатно
-
Спецификация OpenAPIСтандарт описания интерфейсов, на котором построена документация многих сервисовбесплатно
-
Руководство curlПервоисточник по ключам командной строкибесплатно
Было полезно?