Ответ
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 интерактив | Ответ 18+ 🔞
А, слушай, смотри, сейчас тебе разжую, как есть, про эту дичь с передачей данных. Сиди, не дергайся.
Вот есть два главных подхода, как сервер с клиентом могут общаться. Первый — это как будто ты в армии: «Разрешите обратиться!» — «Разрешаю!» — «Так точно!». Это REST API, ёпта.
REST API (Этакая чинная переписка)
- Как общаются: По схеме «Спросил — получил ответ» (Request-Response). Ты, как клиент, каждый раз стучишься в дверь, говоришь «привет», получаешь бумажку и уходишь. Соединение тут же рвётся, как гнилая нитка.
- На чём ездит: Почти всегда поверх обычного HTTP, того самого, по которому сайты грузятся.
- Память: Без состояния (Stateless). Сервер — как золотая рыбка, память — три секунды. Он тебя не помнит. Каждый твой новый запрос должен сам нести все документы: кто ты, что тебе надо. Токен там, куки — ну ты понял.
- Кто начинает: Только клиент. Хочешь узнать, не пришло ли новое письмо? Извини, дружок, опять стучись и спрашивай. Это называется опрос (polling), и он, блядь, тупой как пробка.
- Где юзают: Всё, что не требует мгновенности. Загрузил ленту, отправил форму, удалил запись — классика.
// Ну вот, смотри, как это выглядит в коде. Обычный запрос.
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. Это как провести между клиентом и сервером прямую телефонную трубку и не класть её.
WebSocket (Прямая трубка, болтаем без остановки)
- Как общаются: Двустороннее дуплексное соединение (Full-Duplex). Сначала рукопожатие (handshake), а потом — вуаля! — канал открыт на постоянку. Можешь кричать в трубку ты, может кричать сервер, и всё в реальном времени, без этих «разрешите обратиться».
- Протокол: Специальный,
ws://илиwss://. Не HTTP, а своя, более лёгкая штука. - Память: С состоянием (Stateful). Соединение-то живое! Сервер тебя видит, помнит, может тебе что-то сказать без твоей просьбы.
- Кто начинает: Да кто угодно! Серверу пришла новая цена на биткоин? Он тут же тебе в ухо: «Э, смотри, лопнул пузырь!». Это называется push-модель, и это охуенно удобно.
- Где юзают: Всё, что должно быть живым: чаты (где сообщения летят сразу), онлайн-игры, биржевые тикеры (эти цифры, которые бегут), совместное редактирование документов.
// А вот это уже магия. Создаём задачу для WebSocket.
let socketURL = URL(string: "wss://echo.websocket.org")!
let webSocketTask = URLSession.shared.webSocketTask(with: socketURL)
webSocketTask.resume() // Всё, трубку подняли, соединение висит.
// 1. Можешь ТЫ сказать что-то серверу в любой момент.
let message = URLSessionWebSocketTask.Message.string("Ну чё там по деньгам?")
webSocketTask.send(message) { error in /* ... */ }
// 2. Но главный кайф — ты ВСЕГДА на проводе и слушаешь, что скажет сервер.
func receiveMessage() {
webSocketTask.receive { [weak self] result in
switch result {
case .success(let message):
// Сообщение пришло САМО! Без твоего запроса!
print("Сервер шепчет: (message)")
self?.receiveMessage() // И снова слушаем, это рекурсия, детка.
case .failure(let error):
print("Ой, всё: (error)")
}
}
}
receiveMessage() // Запускаем вечное прослушивание.
Короче, таблица, чтобы вообще ни хуя не путать:
| Признак | REST API | WebSocket |
|---|---|---|
| Модель общения | Как письмо: отправил — жди ответа | Как телефон: поднял трубку и говори |
| Соединение | Короткое, на один запрос | Долгое, постоянное |
| Кто первый пишет | Только клиент | И клиент, и сервер |
| Лишняя нагрузка | Овердохуища заголовков HTTP каждый раз | Почти ничего, после установки связи |
| Идеально для | Получить данные по требованию | Всё, что в реальном времени, интерактив |