← Назад к вопросам

Почему 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)
  • Выбирай инструмент под задачу, не универсального решения нет
Почему Rest редко используется? | PrepBro