Что такое API, REST и RESTful

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


Что такое API

API (Application Programming Interface) — это интерфейс, через который одна программа общается с другой. Ключевое слово — интерфейс: набор правил и контрактов о том, как именно происходит общение.

Простая аналогия: вы приходите в ресторан. Вы не идёте на кухню и не говорите повару что готовить — вы общаетесь с официантом. Официант принимает заказ, передаёт на кухню, приносит результат. Вам не нужно знать как устроена кухня. Официант и есть API.

text
Вы (клиент) → Официант (API) → Кухня (сервер/база данных) ↑ │ └────────────────────────────────────────┘ Готовое блюдо (ответ)

В мире программирования то же самое:

text
Браузер/Приложение → API → Сервер + База данных ↑ │ └───────────────────────────────┘ JSON-ответ

API бывают разные — не только веб. Операционная система предоставляет API для работы с файлами. Библиотека предоставляет API в виде функций. Но когда говорят "сделать API" в контексте backend — обычно имеют в виду веб-API: интерфейс доступный через HTTP.


Что такое REST

REST (Representational State Transfer) — это не технология и не протокол. Это архитектурный стиль: набор принципов того, как должен быть устроен веб-API.

Придумал REST Рой Филдинг в 2000 году в своей диссертации. Он описал 6 принципов, которым должна следовать система чтобы называться REST. На практике важны четыре из них.

Принцип 1: Клиент-сервер

Клиент и сервер разделены и развиваются независимо. Фронтенд не знает как устроена база данных. Бэкенд не знает как выглядит интерфейс. Они общаются только через API.

text
Мобильное приложение ─┐ ├──► API ──► База данных Веб-браузер ──────────┘ Три разных клиента, один API — каждый развивается независимо

Принцип 2: Stateless — без состояния

Каждый запрос самодостаточен. Сервер не помнит предыдущих запросов. Вся информация необходимая для обработки запроса содержится в самом запросе:

text
// Плохо — сервер помнит "текущего пользователя" GET /current-user/todos ← кто текущий пользователь? сервер "помнит" // Хорошо — всё необходимое в запросе GET /users/42/todos Authorization: Bearer eyJ... ← идентификация в каждом запросе

Stateless делает сервер масштабируемым: любой инстанс может обработать любой запрос, потому что не нужно разделять состояние между серверами.

Принцип 3: Единый интерфейс

Это главный принцип REST. Он состоит из нескольких правил:

Ресурсы идентифицируются через URL. В REST всё — это ресурс. Пользователь, задача, заказ — ресурс. URL — это адрес ресурса:

text
/users — коллекция пользователей /users/42 — конкретный пользователь /users/42/todos — задачи конкретного пользователя

Действия определяются HTTP-методами, а не URL:

text
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. Клиент должен понимать что произошло без чтения тела ответа:

text
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:

text
// ❌ Не 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
text
// ❌ Не REST — всегда 200, ошибка в теле HTTP 200 OK {"success": false, "error": "todo not found"} // ✅ REST — статус код отражает результат HTTP 404 Not Found {"error": "todo not found"}
text
// ❌ Не 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.