Что такое API
API (Application Programming Interface) — это контракт, который позволяет одной программе общаться с другой. Веб-API говорит по HTTP: клиент отправляет запрос, сервер возвращает ответ — обычно с данными в формате JSON.
REST (Representational State Transfer) — самый распространённый стиль проектирования таких API. Это не протокол и не библиотека — это набор правил о том, как строить URL, методы и ответы. HTTP передаёт данные; REST говорит, как их организовать.
Центральная идея — ресурс: у каждой сущности, которой управляет ваш API — пользователь, заказ, фотография — есть свой URL, например /users/7.
Правила REST
REST опирается на несколько принципов:
Клиент–сервер — обе стороны разделены и развиваются независимо.
Без состояния — каждый запрос несёт всё, что нужно серверу; между запросами сервер ничего не помнит.
Единый интерфейс — одни и те же URL, методы и коды состояния означают везде одно и то же.
Кэшируемость — ответы могут сообщать «этот ответ можно использовать повторно», экономя обращения к серверу.
Слоистость — прокси, шлюзы и балансировщики нагрузки могут стоять между клиентом и сервером незаметно для обеих сторон.
Один запрос, один ответ
Любое взаимодействие с API — это такой цикл: уходит запрос (метод + URL + необязательное тело), приходит ответ (код состояния + заголовки + тело). Вот один полный цикл на PHP — демонстрация записывает крошечный скрипт-обработчик, запускает с ним в фоне встроенный веб-сервер PHP и останавливает его в конце, поэтому скрипт может выполниться и завершиться сам.
Полный цикл запрос-ответ
Клиент запрашивает GET /users/1; сервер отвечает статусом 200 OK, типом содержимого и телом в формате JSON. Каждая страница этой группы строится на этом цикле.
Вывод: PHP-скрипт
<?php
// Скрипт-обработчик: веб-сервер выполняет этот файл один раз на каждый запрос.
$router = <<<'PHP'
<?php
header("Content-Type: application/json");
echo '{"id": 1, "name": "Ana"}';
PHP;
$routerFile = sys_get_temp_dir() . "/pc-first-request.php";
file_put_contents($routerFile, $router);
// Свободный порт, затем встроенный веб-сервер PHP как дочерний процесс.
$probe = stream_socket_server("tcp://127.0.0.1:0");
$port = (int) explode(":", stream_socket_get_name($probe, false))[1];
fclose($probe);
$server = proc_open(["php", "-S", "127.0.0.1:$port", $routerFile],
[1 => ["file", "/dev/null", "w"], 2 => ["file", "/dev/null", "w"]], $pipes);
do {
usleep(20000);
$up = @fsockopen("127.0.0.1", $port);
} while ($up === false);
fclose($up);
// Один полный цикл запрос-ответ.
$context = stream_context_create(["http" => ["ignore_errors" => true]]);
$body = file_get_contents("http://127.0.0.1:$port/users/1", false, $context);
[, $status] = explode(" ", $http_response_header[0], 2);
$type = "";
foreach ($http_response_header as $headerLine) {
if (stripos($headerLine, "Content-Type:") === 0) {
$type = trim(substr($headerLine, 13));
}
}
echo "запрос: GET /users/1\n";
echo "статус: $status\n";
echo "тип: $type\n";
echo "тело: $body\n";
proc_terminate($server);
proc_close($server);
unlink($routerFile);
Методы, коды состояния и ограничения
Методы HTTP соответствуют четырём операциям над данными (CRUD):
GET прочитать ресурс · POST создать · PUT заменить · PATCH изменить часть · DELETE удалить.
Коды состояния сообщают, как всё прошло: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error.
И у REST есть честные ограничения: он не рассчитан на потоки в реальном времени, ответ может нести больше или меньше того, что хотел клиент, а версионирование публичного API требует дисциплины. Знать ограничения — часть знания стиля.