Что такое API, REST и RESTful
Эти три термина звучат на каждом собеседовании и в каждом описании вакансии. При этом многие разработчики используют их как синонимы, хотя это разные вещи. Разберём каждый по порядку.
Что такое API
API (Application Programming Interface) — это интерфейс, через который одна программа общается с другой. Ключевое слово — интерфейс: набор правил и контрактов о том, как именно происходит общение.
Простая аналогия: вы приходите в ресторан. Вы не идёте на кухню и не говорите повару что готовить — вы общаетесь с официантом. Официант принимает заказ, передаёт на кухню, приносит результат. Вам не нужно знать как устроена кухня. Официант и есть API.
Вы (клиент) → Официант (API) → Кухня (сервер/база данных)
↑ │
└────────────────────────────────────────┘
Готовое блюдо (ответ)
В мире программирования то же самое:
Браузер/Приложение → API → Сервер + База данных
↑ │
└───────────────────────────────┘
JSON-ответ
API бывают разные — не только веб. Операционная система предоставляет API для работы с файлами. Библиотека предоставляет API в виде функций. Но когда говорят "сделать API" в контексте backend — обычно имеют в виду веб-API: интерфейс доступный через HTTP.
Что такое REST
REST (Representational State Transfer) — это не технология и не протокол. Это архитектурный стиль: набор принципов того, как должен быть устроен веб-API.
Придумал REST Рой Филдинг в 2000 году в своей диссертации. Он описал 6 принципов, которым должна следовать система чтобы называться REST. На практике важны четыре из них.
Принцип 1: Клиент-сервер
Клиент и сервер разделены и развиваются независимо. Фронтенд не знает как устроена база данных. Бэкенд не знает как выглядит интерфейс. Они общаются только через API.
Мобильное приложение ─┐
├──► API ──► База данных
Веб-браузер ──────────┘
Три разных клиента, один API — каждый развивается независимо
Принцип 2: Stateless — без состояния
Каждый запрос самодостаточен. Сервер не помнит предыдущих запросов. Вся информация необходимая для обработки запроса содержится в самом запросе:
// Плохо — сервер помнит "текущего пользователя"
GET /current-user/todos ← кто текущий пользователь? сервер "помнит"
// Хорошо — всё необходимое в запросе
GET /users/42/todos
Authorization: Bearer eyJ... ← идентификация в каждом запросе
Stateless делает сервер масштабируемым: любой инстанс может обработать любой запрос, потому что не нужно разделять состояние между серверами.
Принцип 3: Единый интерфейс
Это главный принцип REST. Он состоит из нескольких правил:
Ресурсы идентифицируются через URL. В REST всё — это ресурс. Пользователь, задача, заказ — ресурс. URL — это адрес ресурса:
/users — коллекция пользователей
/users/42 — конкретный пользователь
/users/42/todos — задачи конкретного пользователя
Действия определяются HTTP-методами, а не URL:
GET /todos — получить список
POST /todos — создать новую
GET /todos/1 — получить одну
PUT /todos/1 — обновить полностью
PATCH /todos/1 — обновить частично
DELETE /todos/1 — удалить
URL отвечает на вопрос "что", метод — на вопрос "что сделать".
Представление ресурса отделено от самого ресурса. Один и тот же ресурс может быть представлен по-разному — JSON, XML, HTML — в зависимости от того что запрашивает клиент через заголовок Accept.
Принцип 4: Кешируемость
Ответы должны явно указывать можно ли их кешировать. GET-запросы как правило кешируются, POST/PUT/DELETE — нет. Это позволяет CDN и браузерам не делать лишние запросы к серверу.
HTTP-методы и статус коды в контексте REST
REST использует HTTP как протокол, и семантика методов важна:
| Метод | Действие | Идемпотентен? |
|---|---|---|
GET | Получить ресурс | Да |
POST | Создать ресурс | Нет |
PUT | Заменить ресурс целиком | Да |
PATCH | Обновить частично | Нет |
DELETE | Удалить ресурс | Да |
Идемпотентность — если выполнить запрос несколько раз, результат тот же что и от одного. DELETE /todos/1 можно вызвать трижды — после первого раза задача удалена, следующие вызовы ничего не меняют (возвращают 404, но состояние системы не меняется).
Статус коды
Статус код — часть контракта REST. Клиент должен понимать что произошло без чтения тела ответа:
2xx — успех
200 OK — запрос выполнен
201 Created — ресурс создан (ответ на POST)
204 No Content — успех, тело пустое (ответ на DELETE)
4xx — ошибка клиента
400 Bad Request — неверный запрос (невалидные данные)
401 Unauthorized — не аутентифицирован
403 Forbidden — аутентифицирован, но нет доступа
404 Not Found — ресурс не найден
409 Conflict — конфликт (например, email уже занят)
422 Unprocessable — данные валидны по формату, но не по логике
5xx — ошибка сервера
500 Internal Server Error — что-то сломалось на сервере
503 Service Unavailable — сервис временно недоступен
Типичная ошибка новичков — возвращать 200 OK с телом {"error": "not found"}. Это нарушает контракт REST: клиент смотрит на статус код, а не парсит тело чтобы понять успех это или ошибка.
Что такое RESTful API
RESTful API — это веб-API, который следует принципам REST. Приставка "-ful" означает "в полной мере". Если API соответствует принципам Филдинга — его можно назвать RESTful.
На практике термины "REST API" и "RESTful API" используются как синонимы — разница только в степени строгости соответствия принципам.
REST vs не REST — на примере Todo API
Разница становится понятнее на конкретных примерах. Вот хорошие и плохие варианты для нашего Todo API:
// ❌ Не REST — действие в URL, игнорирование методов
POST /getTodos
POST /createTodo
POST /deleteTodo?id=1
POST /markTodoAsDone?id=1
GET /todo/delete/1
// ✅ REST — URL это ресурс, метод это действие
GET /api/todos
POST /api/todos
DELETE /api/todos/1
PUT /api/todos/1
// ❌ Не REST — всегда 200, ошибка в теле
HTTP 200 OK
{"success": false, "error": "todo not found"}
// ✅ REST — статус код отражает результат
HTTP 404 Not Found
{"error": "todo not found"}
// ❌ Не REST — глагол в URL
POST /api/todos/1/markDone
POST /api/todos/1/archive
GET /api/getAllTodos
// ✅ REST — глагол выражен методом, URL — существительное
PUT /api/todos/1 (с телом {"done": true})
PUT /api/todos/1 (с телом {"archived": true})
GET /api/todos
Когда REST не подходит
REST хорош для большинства задач, но не универсален. Есть случаи когда выбирают другой подход:
GraphQL — когда клиенту нужна гибкость в выборе полей. Вместо нескольких REST-запросов — один запрос с описанием нужных данных. Популярен в мобильных приложениях где важен трафик.
gRPC — когда нужна высокая производительность и строгая типизация между сервисами. Использует бинарный протокол (protobuf) вместо JSON. Стандарт для межсервисного взаимодействия в микросервисах.
WebSocket — когда нужна двусторонняя связь в реальном времени: чат, онлайн-игры, live-уведомления. REST работает по схеме запрос-ответ, WebSocket держит постоянное соединение.
На собеседовании на позицию backend-разработчика достаточно понимать REST и уметь объяснить почему выбирают альтернативы — это уже уровень осознанного выбора инструмента.
Вопросы на собеседовании
Q: Что такое API? Чем веб-API отличается от любого другого API?
A: API — интерфейс через который одна программа общается с другой: набор правил и контрактов взаимодействия. Веб-API — частный случай: интерфейс доступный по сети через HTTP. Любая библиотека тоже предоставляет API — в виде функций и классов, но не через сеть.
Q: Что такое REST? Это протокол или технология?
A: Ни то ни другое. REST — архитектурный стиль: набор принципов проектирования веб-API, описанных Роем Филдингом в 2000 году. Главные: клиент-сервер, stateless, единый интерфейс (ресурсы в URL, действия в HTTP-методах), кешируемость.
Q: Что значит stateless в контексте REST?
A: Сервер не хранит состояние между запросами. Каждый запрос самодостаточен — содержит всю информацию необходимую для обработки: идентификацию пользователя, параметры, данные. Это делает систему масштабируемой: любой сервер может обработать любой запрос.
Q: Чем PUT отличается от PATCH?
A: PUT заменяет ресурс целиком — нужно передать все поля. PATCH обновляет частично — только изменённые поля. PUT идемпотентен: повторный вызов с теми же данными не меняет результат. PATCH технически нет, хотя на практике часто реализуют идемпотентно.
Q: Почему нельзя возвращать 200 OK с телом {"error": "not found"}?
A: Нарушает контракт REST и HTTP. Клиент (браузер, мобильное приложение, другой сервис) смотрит на статус код чтобы понять успех или ошибка — без парсинга тела. 200 означает успех. Middleware, прокси, CDN тоже ориентируются на статус коды. Правильно: 404 Not Found с телом {"error": "not found"}.
Q: Чем отличаются 401 и 403?
A: 401 Unauthorized — пользователь не аутентифицирован: не передал токен или токен невалидный. Буквально "мы не знаем кто ты". 403 Forbidden — пользователь аутентифицирован, но у него нет прав на это действие. "Мы знаем кто ты, но тебе нельзя".
Q: Что такое идемпотентность? Какие HTTP-методы идемпотентны?
A: Операция идемпотентна если повторное выполнение с теми же параметрами даёт тот же результат. GET, PUT, DELETE — идемпотентны. POST — нет: каждый вызов создаёт новый ресурс. PATCH — зависит от реализации.
Q: Когда REST не лучший выбор?
A: Когда нужна гибкость запросов от клиента — GraphQL. Когда нужна высокая производительность и строгая типизация между сервисами — gRPC. Когда нужна двусторонняя связь в реальном времени — WebSocket.