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

Когда нельзя использовать REST?

1.7 Middle🔥 71 комментариев
#REST API и микросервисы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Когда REST неэффективен или непрактичен

REST — отличный архитектурный стиль для большинства веб-приложений, но есть сценарии, где он показывает свои слабости. Понимание этих ограничений критично для выбора правильного подхода.

1. Real-Time Communication (Реал-тайм взаимодействие)

REST основан на модели запрос-ответ. Сервер не может инициировать передачу данных клиенту.

Проблемы:

  • Polling: клиент постоянно спрашивает сервер → избыточный трафик
  • Задержка: нет мгновенных уведомлений
  • Нагрузка: краш при миллионах опросов

Когда критично:

  • Чаты и мессенджеры
  • Совместное редактирование документов
  • Трейдинг и котировки акций
  • Multiplayer игры
  • IoT устройства

Решение:

@Configuration
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(chatHandler(), "/ws/chat");
    }
}

@Component
public class ChatHandler extends TextWebSocketHandler {
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        // Отправляем данные всем клиентам активно
        for (WebSocketSession s : sessions) {
            s.sendMessage(new TextMessage(message.getPayload()));
        }
    }
}

2. Сложные запросы (Over-fetching и Under-fetching)

REST предоставляет фиксированную структуру данных для каждого endpoint.

Over-fetching:

GET /api/users/123
// Возвращает все поля, но нужны только name и email
{
  "id": 123,
  "name": "John",
  "email": "john@example.com",
  "phone": "+7-900-000-0000",
  "address": "Moscow",
  "socialAccounts": [...]
}

Under-fetching (N+1 проблема):

GET /api/users/123          // первый запрос
GET /api/users/123/orders   // второй запрос
GET /api/products/456       // третий запрос
// Нужно 1+N запросов вместо 1

Решение — GraphQL:

query {
  user(id: 123) {
    name
    email
    orders {
      id
      total
      items {
        name
        price
      }
    }
  }
}

3. Высоконагруженные системы

REST требует HTTP overhead: заголовки, TCP соединение, SSL/TLS handshake.

Проблемы:

  • Высокая задержка (latency)
  • Большой расход памяти на соединения
  • Сложно масштабировать

Где критично:

  • Real-time stock market feeds
  • IoT сенсоры, отправляющие тысячи данных в секунду
  • Video streaming

Решение — gRPC:

public class MetricsServer {
    private Server server;

    public void start() throws IOException {
        server = ServerBuilder.forPort(50051)
            .addService(new MetricsServiceImpl())
            .build()
            .start();
    }
}

// Использует Protocol Buffers (меньше размер)
// HTTP/2 (мультиплексирование)
// Двусторонний streaming

4. Стриминг данных (Stream Processing)

REST завершает запрос, когда все данные отправлены. Нет концепции потока данных.

Когда критично:

  • Загрузка больших файлов
  • Видеостриминг
  • Получение логов в реал-тайм
  • Event streaming (Kafka)

Решение — SSE или WebSocket:

@GetMapping("/api/logs/stream")
public SseEmitter streamLogs() {
    SseEmitter emitter = new SseEmitter();
    new Thread(() -> {
        try {
            for (String log : logReader.readLive()) {
                emitter.send(new SseEmitter.SseEventBuilder()
                    .id(UUID.randomUUID().toString())
                    .data(log)
                    .build());
            }
        } catch (IOException e) {
            emitter.completeWithError(e);
        }
    }).start();
    return emitter;
}

5. Версионирование API и обратная совместимость

REST полагается на изменение структуры JSON, что усложняет версионирование.

Проблемы:

// Версия 1: GET /api/users/123 → {"name": "John", "age": 30}
// Версия 2: Добавили поле "email"
// Версия 3: Переименовали "age" → "years"
// Версия 4: Удалили поле "age"
// Нужны сложные миграции и multiple endpoints

6. Сложные транзакции и ACID операции

REST не гарантирует, что несколько запросов выполнятся как одна атомарная операция.

Проблема:

// Перевод денег между аккаунтами
POST /api/accounts/1/withdraw (вывести 100) → успех
POST /api/accounts/2/deposit (внести 100) → FAIL
// Деньги потеряны!

Итоговая таблица альтернатив

СценарийАльтернативаПричина
Real-time чатWebSocket, Socket.IOДвусторонняя коммуникация
Сложные запросыGraphQL, gRPCГибкость, эффективность
ВысоконагруженныеgRPC, AMQP, KafkaНизкая задержка
Стриминг данныхWebSocket, SSE, KafkaНепрерывный поток
Видео/медиаHLS, DASH, RTMPСпециализированные
МикросервисыgRPCПроизводительность

Вывод

REST остаётся золотым стандартом для типичных CRUD операций. Опытный разработчик должен сознательно выбирать инструмент в зависимости от требований, а не использовать REST везде.