В чем разница между REST API и WebSocket?

«В чем разница между REST API и WebSocket?» — вопрос из категории Сети, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

REST API (Representational State Transfer)

  • Модель связи: Запрос-ответ (Request-Response). Клиент инициирует соединение, сервер отвечает, соединение закрывается.
  • Протокол: Обычно поверх HTTP/HTTPS.
  • Состояние (State): Stateless. Каждый запрос независим и содержит всю необходимую информацию (например, токен аутентификации). Сервер не хранит состояние сессии между запросами.
  • Направление: Одностороннее (клиент → сервер). Для получения новых данных клиент должен опрашивать (poll) сервер.
  • Использование: CRUD-операции (создание, чтение, обновление, удаление данных), стандартные веб-сервисы.
    // Пример REST-запроса в iOS
    let url = URL(string: "https://api.example.com/posts/1")!
    URLSession.shared.dataTask(with: url) { data, response, error in
    // Обрабатываем ОДИН ответ на ОДИН запрос
    if let data = data {
        let post = try? JSONDecoder().decode(Post.self, from: data)
    }
    }.resume()

WebSocket

  • Модель связи: Двусторонняя дуплексная (Full-Duplex) по постоянному соединению. После установки соединения (handshake) и клиент, и сервер могут отправлять сообщения в любое время.
  • Протокол: ws:// или wss:// (поверх TCP).
  • Состояние (State): Stateful. Соединение поддерживается, сервер может "помнить" клиента.
  • Направление: Двустороннее (клиент ⇄ сервер). Сервер может сам инициировать отправку данных (push-модель).
  • Использование: Приложения реального времени: чаты, онлайн-игры, биржевые тикеры, collaborative editing, live-уведомления.
    
    // Пример WebSocket в iOS (URLSessionWebSocketTask)
    let socketURL = URL(string: "wss://echo.websocket.org")!
    let webSocketTask = URLSession.shared.webSocketTask(with: socketURL)
    webSocketTask.resume() // Устанавливаем постоянное соединение

// 1. Отправка сообщения на сервер let message = URLSessionWebSocketTask.Message.string("Hello Server") webSocketTask.send(message) { error in / ... / }

// 2. Постоянное прослушивание сообщений ОТ сервера func receiveMessage() { webSocketTask.receive { [weak self] result in switch result { case .success(let message): // Обрабатываем сообщение от сервера (может прийти в ЛЮБОЙ момент) print("Received: (message)") self?.receiveMessage() // Слушаем следующее сообщение case .failure(let error): print("Error: (error)") } } } receiveMessage()



**Сравнительная таблица:**
| Характеристика | REST API | WebSocket |
|---|---|---|
| **Модель** | Запрос-Ответ | Дуплексный поток сообщений |
| **Соединение** | Временное, на запрос | Постоянное |
| **Инициатор** | Только клиент | Клиент и сервер |
| **Накладные расходы** | Высокие (заголовки HTTP на каждый запрос) | Низкие (после handshake) |
| **Лучший сценарий** | Получение данных по требованию | Real-time интерактив |