gRPC в Swift: когда и зачем это реально нужно

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

gRPC в Swift: когда это не просто модно, а нужно

Представьте: вы пишете iOS-приложение для управления умным домом. Команды отправляются каждую секунду, задержка в 100 мс — уже катастрофа. Или вы делаете стриминговый сервис, где видео, аудио и телеметрия летят одновременно. REST тут начнет «тормозить» и курить в сторонке. Знакомьтесь — gRPC в Swift.

Но давайте честно: gRPC — не серебряная пуля. Иногда простой JSON на HTTP/1.1 работает лучше. В этой статье мы разберем, когда gRPC в iOS оправдан, когда лучше оставить REST, и как это выглядит в реальном коде на Swift.

Я не буду лить воду. Только практика, примеры и конкретные сценарии. Поехали.

Что такое gRPC (очень кратко, для тех, кто пропустил)

gRPC — это RPC-фреймворк от Google, который использует Protocol Buffers (protobuf) для сериализации данных и HTTP/2 для транспорта. Он поддерживает:

  • Унарные вызовы (как обычный REST)
  • Серверный стриминг
  • Клиентский стриминг
  • Бидирекциональный стриминг

На Swift есть официальная библиотека grpc-swift (Swift Package Manager), которая позволяет и клиенту, и серверу работать на Swift. Да, вы можете написать сервер на Swift с gRPC — это не шутка.

Когда gRPC в Swift — ваш лучший друг

1. Высокая нагрузка и низкая задержка

Если ваше приложение отправляет сотни запросов в секунду (например, трейдинг, гейминг, IoT), gRPC выигрывает за счет:

  • HTTP/2 — мультиплексирование, сжатие заголовков
  • Бинарный протокол — protobuf быстрее парсится, чем JSON
  • Keep-alive соединения — не нужно каждый раз открывать TCP-рукопожатие

Пример из жизни: приложение для мониторинга серверов. Каждую секунду приходит 1000 метрик. На REST — 1000 TCP-соединений, на gRPC — одно долгоживущее. Разница в нагрузке на батарею — в разы.

2. Стриминг данных

REST с его «запрос-ответ» не умеет стримить. А gRPC — умеет. Если вам нужно:

  • Получать обновления курса валют в реальном времени
  • Стримить аудио/видео
  • Получать логи с сервера по мере их появления

Тогда gRPC — ваш выбор. Вот как выглядит серверный стриминг на Swift:

// Определение в .proto
service StreamService {
    rpc SubscribeToUpdates(Empty) returns (stream Update) {}
}

// Клиент на Swift
let client = StreamServiceAsyncClient(channel: channel)
let updates = client.subscribeToUpdates(Empty())

for try await update in updates {
    print("Получено обновление: \(update.message)")
}

Обратите внимание: for try await — это Swift Concurrency. gRPC-Swift отлично с этим работает.

3. Микросервисы на Swift (да, такое бывает)

Вы можете написать весь бэкенд на Swift (Vapor, Hummingbird) и использовать gRPC для внутренней коммуникации между микросервисами. Плюсы:

  • Общий код моделей (protobuf генерирует Swift-структуры)
  • Строгая типизация
  • Встроенная поддержка таймаутов, ретраев, балансировки
// Сервер на Swift
final class GreeterProvider: GreeterAsyncProvider {
    func sayHello(request: HelloRequest, context: GRPCAsyncServerCallContext) async throws -> HelloReply {
        return HelloReply.with { $0.message = "Привет, \(request.name)!" }
    }
}

Этот код — полноценный gRPC-сервер, который запускается на любом Linux/macOS сервере.

4. Когда у вас строгая контрактная система

Protobuf-файлы — это единый источник правды. Вы описали API в .proto, сгенерировали код для Swift, Go, Python — и все говорят на одном языке. Никаких «ой, а тут поле опциональное, а тут нет».

Для больших команд это спасение. Особенно если клиент и сервер пишут разные люди.

Когда gRPC в Swift — лишняя сложность

Давайте без фанатизма. Есть сценарии, где gRPC только мешает:

1. Простое CRUD-приложение

Если вы делаете список покупок или заметки — REST с JSON будет проще. gRPC требует:

  • Установки protobuf-компилятора
  • Генерации кода
  • Поддержки HTTP/2 на сервере

Для маленького проекта это оверхед, который не окупается.

2. Публичное API для браузеров

Браузеры не умеют нативно работать с gRPC (без gRPC-Web, который добавляет прослойку). Если ваш клиент — веб, лучше оставить REST или GraphQL.

3. Команда не знает protobuf

Если ваши разработчики никогда не работали с Protocol Buffers, первое время будет больно. Ошибки компиляции, странные сообщения, проблемы с совместимостью версий. REST с JSON — понятнее.

Как начать использовать gRPC в Swift: пошаговый чеклист

  1. Добавьте зависимость через SPM: https://github.com/grpc/grpc-swift.git
  2. Опишите API в .proto файле
  3. Сгенерируйте Swift-код с помощью protoc-gen-grpc-swift
  4. Создайте клиент или сервер на основе сгенерированных классов
  5. Запустите — и готово

Вот минимальный пример клиента, который отправляет запрос и получает ответ:

import GRPC
import NIOCore
import NIOPosix

let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
defer { try! group.syncShutdownGracefully() }

let channel = try GRPCChannelPool.with(
    target: .host("localhost", port: 50051),
    transportSecurity: .plaintext,
    eventLoopGroup: group
)

let client = EchoAsyncClient(channel: channel)
let response = try await client.sayHello(HelloRequest.with { $0.name = "Мир" })
print("Ответ: \(response.message)")

Видите? Ничего сложного. Это работает из коробки.

Итог: стоит ли использовать gRPC в Swift?

Блоги

Рекомендаций по книгам