Что такое 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 + необязательное тело), возвращается ответ (код состояния + заголовки + тело). Вот один полный цикл на Python — демонстрация запускает крошечный локальный сервер в фоновом потоке, поэтому программа может сама выполниться и завершиться.
Полный цикл запроса и ответа
Клиент запрашивает GET /users/1; сервер отвечает кодом состояния 200 OK, типом содержимого и телом в формате JSON. Каждая страница этого раздела строится на этом цикле.
Одна деталь демонстрации: обработчик переопределяет log_message пустым методом. Базовый класс выводил бы строку журнала с отметкой времени для каждого запроса, а демонстрации нужен ровно показанный вывод — и ничего больше.
Вывод: полная программа на Python
import threading
import urllib.request
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(b'{"id": 1, "name": "Ana"}')
def log_message(self, fmt, *args):
pass # отключаем встроенный журнал запросов, чтобы вывод оставался чистым
# Маленький сервер для демонстрации (настоящий блокировался бы на serve_forever).
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
port = server.server_address[1]
threading.Thread(target=server.serve_forever, daemon=True).start()
with urllib.request.urlopen(f"http://127.0.0.1:{port}/users/1") as resp:
print("запрос: GET /users/1")
print("статус:", resp.status, resp.reason)
print("тип: ", resp.headers["Content-Type"])
print("тело: ", resp.read().decode())
server.shutdown()
Методы, коды состояния и ограничения
Методы 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 требует дисциплины. Знать ограничения — часть знания самого стиля.