← Назад к вопросам
Почему Rest редко используется?
3.0 Senior🔥 101 комментариев
#Docker, Kubernetes и DevOps
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
REST в реальных проектах: почему его использование ограничено
Контекст вопроса
Вопрос несколько некорректно сформулирован. REST используется повсеместно (Google API, AWS, GitHub), но в его чистом виде он редко применяется. На практике большинство API称為 себя REST, но не соответствуют ограничениям Роя Филдинга.
Чистый REST (Richardson Maturity Model)
Рой Филдинг определил REST в диссертации 2000 года как архитектурный стиль с ограничениями:
Level 0: XML-RPC (один URL, всё через POST)
├─ POST /api {"method": "createUser", "params": {...}}
Level 1: Resources (разные URL для ресурсов)
├─ POST /users (создать)
├─ GET /users/123 (получить)
├─ PUT /users/123 (обновить)
Level 2: HTTP Verbs (правильные методы HTTP)
├─ POST /users
├─ GET /users/123
├─ PUT /users/123
├─ DELETE /users/123
Level 3: HATEOAS (Hypermedia As The Engine Of Application State)
├ {
├ "id": 123,
├ "name": "John",
├ "links": [
├ {"rel": "self", "href": "/users/123"},
├ {"rel": "all", "href": "/users"},
├ {"rel": "posts", "href": "/users/123/posts"}
├ ]
├ }
Мало кто использует Level 3.
Проблемы REST в реальности
1. Overfetching (получение лишних данных)
// Фронтенд хочет только имя и email
// GET /users/123
// Но получает весь объект:
{
"id": 123,
"name": "John",
"email": "john@example.com",
"phone": "+1234567890",
"address": "...",
"birthDate": "1990-01-01",
"ssn": "123-45-6789",
"medicalRecords": [...], // Ненужный объём данных!
"bankAccount": {...}
}
// Вот почему GraphQL лучше:
query {
user(id: 123) {
name
email
}
}
2. Underfetching (недостаточно данных в одном запросе)
// Нужно получить пользователя и его посты
// REST требует 2+ запроса:
GET /users/123 // получили пользователя
GET /users/123/posts // получили посты
GET /posts/{postId}/comments // получили комментарии
// Всего 3+ запроса (N+1 problem)
// GraphQL делает это в одном:
query {
user(id: 123) {
name
posts {
title
comments {
text
}
}
}
}
3. Версионирование API
Kak поддерживать версионирование?
1. В URL: /api/v1/users vs /api/v2/users
├─ Много дублирования кода
├─ Сложно с миграцией
2. В Header: X-API-Version: 2
├─ Неявно, трудно отследить
3. Content-Type: application/vnd.company.v2+json
├─ Сложно для клиентов
РЕШЕНИЕ: GraphQL — клиент запрашивает ровно то, что нужно
4. Сложность со сложными операциями
// Как в REST заказать товары?
// Option 1: разные endpoints
POST /orders
POST /orders/{id}/items // добавить товар 1
POST /orders/{id}/items // добавить товар 2
POST /orders/{id}/checkout
// Это 4 запроса вместо одного!
// Option 2: GraphQL mutation
mutation {
createOrder(input: {
items: [{productId: 1, qty: 2}, {productId: 2, qty: 1}]
paymentMethod: "credit_card"
}) {
id
total
status
}
}
5. Кэширование
// REST полагается на HTTP кэширование
GET /users/123
Cache-Control: max-age=3600
// Но что если:
// - Данные обновились?
// - Нужен кэш для POST?
// - Как кэшировать сложные запросы?
// ПРОБЛЕМА: POST не кэшируется по HTTP стандарту
// Но в GraphQL всё через POST!
// GraphQL нужны свои решения кэширования
6. Методы HTTP не идеальны
// PUT vs PATCH vs POST?
PUT /users/123 // заменить весь объект
PATCH /users/123 // частичное обновление
POST /users/123 // ???
// На практике:
// - PATCH плохо поддерживается (требует JSON Patch)
// - POST используют везде для обновлений
// - PUT используют редко
// GraphQL просто:
mutation {
updateUser(id: 123, data: {name: "Jane"}) {
id
name
}
}
7. Обработка ошибок
// REST попытка стандартизировать ошибки через HTTP статусы:
200 OK // успешно
201 Created
400 Bad Request
404 Not Found
500 Internal Server Error
// Но проблемы:
GET /users/invalid-id
// Вернёт 400? 404? Зависит от реализации!
// Частичный успех в операции?
POST /orders/bulk-create // создаём 100 заказов
// 50 успешно, 50 ошибок
// HTTP статус: 200? 400? 500?
// GraphQL явно возвращает:
{
"data": {...}, // что удалось
"errors": [...] // что не удалось
}
Альтернативы REST
1. GraphQL
Преимущества:
✓ Клиент запрашивает ровно то, что нужно
✓ Сильная типизация
✓ Одна точка входа вместо множества endpoints
✓ Excellent для мобильных (меньше трафика)
✓ Self-documenting (schema = документация)
Недостатки:
✗ Кривая обучения
✗ Кэширование сложнее
✗ Запросы могут быть дорогими (глубокий граф)
✗ Оверхед парсинга
# GraphQL запрос
query {
user(id: 123) {
name
email
posts(limit: 5) {
title
content
}
}
}
2. gRPC
Преимущества:
✓ Очень быстро (Protocol Buffers binary)
✓ Сильная типизация
✓ Двусторонний streaming
✓ Идеально для микросервисов
Недостатки:
✗ Не работает в браузере (нужен gRPC Web)
✗ Сложнее отлаживать
✗ Меньше экосистема
service UserService {
rpc GetUser (UserRequest) returns (User) {}
rpc ListUsers (Empty) returns (stream User) {}
}
3. Apache Thrift
- Похож на gRPC
- Меньше популярности
- Facebook, Instagram использовали
4. SOAP (не используется в новых проектах)
Химерный формат XML
Очень многословный
Сегодня это анахронизм
Когда REST ещё уместен
// 1. Простые операции с ресурсами
GET /books
GET /books/{id}
POST /books
PUT /books/{id}
DELETE /books/{id}
// 2. Публичные API (простота для клиентов)
Google Maps API
Twitter API
GitHub API
// 3. Микросервисы между собой
// Хотя gRPC часто предпочтительнее
// 4. Legacy системы
// Просто переписывать дорого
Современный подход
Вместо выбора "REST vs GraphQL vs gRPC"
Выбирай инструмент под задачу:
1. Фронтенд-бэкенд в веб? → GraphQL
2. Микросервисы? → gRPC
3. Публичный API для разных клиентов? → REST
4. Real-time приложение? → WebSocket + GraphQL/gRPC
5. Простой CRUD? → REST подойдёт
Реальный пример: современный стек
// Backend (Spring Boot)
@RestController // для простых endpoints
public class PublicController { ... }
@Service // для GraphQL
public class GraphQLService { ... }
// gRPC для микросервисов (в отдельном модуле)
service UserServiceGrpc { ... }
// WebSocket для real-time
@WebSocketHandler
public class ChatHandler { ... }
Итог
- REST не редко используется — он везде
- REST в чистом виде редко используется — Level 3 HATEOAS редкость
- REST имеет проблемы: overfetching, underfetching, N+1 queries
- Альтернативы:
- GraphQL (лучше для фронтенда)
- gRPC (лучше для микросервисов)
- Гибридный подход (REST + GraphQL)
- Выбирай инструмент под задачу, не универсального решения нет