Serverless на Swift: когда мобильный разработчик идёт в облако
Вы пишете на Swift для iOS, macOS или watchOS. Ваш код красив, безопасен и быстр. Но рано или поздно возникает вопрос: а что, если вынести бэкенд-логику на тот же язык? Не плодить сущности с Python, Node.js или Go, а просто взять и написать облачную функцию на родном Swift?
Хорошая новость: это уже реальность. Serverless функции на Swift работают на AWS Lambda, Google Cloud Run и даже Vercel. Да, экосистема не такая зрелая, как у JavaScript, но для мобильных разработчиков, которые хотят контролировать и клиент, и сервер, это золотая жила.
В этой статье разберём, как запустить Swift в serverless-окружении, какие есть подводные камни и где взять готовые шаблоны. Поехали.
Почему Swift, а не Python или Node.js?
Давайте честно: если вам нужно быстро набросать парсер или простой API, Python или Node.js будут удобнее. Но у Swift есть козыри, которые перевешивают для продакшн-нагрузок:
- Производительность — Swift компилируется в нативный код. На AWS Lambda это даёт прирост скорости до 2-3 раз по сравнению с Node.js на одинаковых бюджетах памяти.
- Типизация и безопасность — Optionals, строгая типизация, отсутствие nil-объектов. Ошибки, которые в Python вылезут в рантайме, в Swift отловятся на этапе компиляции.
- Единый стек — если вы iOS-разработчик, вам не нужно учить второй язык для бэкенда. Одна кодовая база, одни структуры, одна логика.
- Экосистема Vapor — самый популярный Swift-фреймворк для сервера, который отлично адаптируется под serverless.
Конечно, есть минусы: размер бинарника (около 15-30 МБ против 500 КБ для Node.js) и меньше готовых библиотек. Но для микросервисов и API-шлюзов это не критично.
Техническая основа: как Swift работает на AWS Lambda
Amazon официально поддерживает Swift через Custom Runtime. Вы не используете встроенный runtime Node.js или Python — вы упаковываете свой исполняемый файл в ZIP и загружаете в Lambda.
Вот как это выглядит на уровне архитектуры:
- Lambda вызывает ваш бинарник как shell-команду.
- Ваш код читает событие из stdin (JSON), обрабатывает его и пишет ответ в stdout.
- Runtime API (через HTTP) используется для отправки отчётов и ошибок.
Звучит сложно? На практике мы используем готовый шаблон Swift AWS Lambda Runtime от Apple. Он берёт на себя всю рутину.
Пример: простой Lambda-обработчик на Swift
Создадим функцию, которая принимает имя пользователя и возвращает приветствие. Это классический hello-world для serverless.
// Импортируем библиотеку от Apple
import AWSLambdaRuntime
import AWSLambdaEvents
// Структуры для входа и выхода
struct GreetingRequest: Codable {
let name: String
}
struct GreetingResponse: Codable {
let message: String
}
// Основной обработчик
Lambda.run { (context, request: GreetingRequest, callback: @escaping (Result<GreetingResponse, Error>) -> ()) in
let response = GreetingResponse(message: "Привет, \(request.name)! Добро пожаловать в serverless на Swift.")
callback(.success(response))
}
Этот код компилируется в бинарник. Вы упаковываете его в ZIP вместе с библиотеками (статическая линковка) и загружаете в AWS Lambda. Runtime сам найдёт точку входа.
Важно: для продакшна используйте Docker-образ на основе Amazon Linux 2, иначе могут быть проблемы с glibc.
Сборка и деплой: пошаговый план
Чтобы не тратить время на танцы с бубном, используйте готовую утилиту aws-lambda-swift-sam. Это надстройка над AWS SAM (Serverless Application Model).
- Установите Swift 5.7+ — обязателен, так как более старые версии не поддерживают новый runtime.
- Создайте проект:
swift package init --type executable - Добавьте зависимость в Package.swift:
.package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "1.0.0") - Соберите для Linux:
docker run --rm -v "$PWD":/workspace -w /workspace swift:5.7-amazonlinux2 swift build -c release - Упакуйте:
zip -j lambda.zip .build/release/YourProject - Загрузите в Lambda через консоль AWS или CLI.
После деплоя ваша функция будет готова принимать запросы через API Gateway. Время холодного старта — около 1-2 секунд, что терпимо для большинства сценариев.
Альтернативы AWS Lambda: куда ещё можно запустить Swift
AWS Lambda — не единственный игрок на поле. Рассмотрим другие платформы, где Swift чувствует себя неплохо.
Google Cloud Run
Cloud Run работает с контейнерами, поэтому вы просто упаковываете Swift-приложение в Docker. Плюс — нет лимита на размер бинарника. Минус — вы платите за время работы контейнера, а не за каждый вызов.
// Простой HTTP-сервер на Vapor, который работает в Cloud Run
import Vapor
var env = try Environment.detect()
let app = Application(env)
defer { app.shutdown() }
app.get("hello") { req -> String in
return "Hello from Swift on Cloud Run!"
}
try app.run()
Этот код запускается в контейнере. Cloud Run сам масштабирует количество инстансов до нуля, когда нет трафика. Идеально для микросервисов.
Vercel (через Swift Lambda Runtime)
Vercel поддерживает кастомные runtime. Можно написать адаптер и запустить Swift-функцию как Serverless Function. Однако официальной поддержки нет — придётся использовать community-решения.
Fly.io
Платформа, которая запускает приложения близко к пользователю. Swift поддерживается через Docker. Хороший вариант для real-time приложений.
Сравнение платформ для Swift serverless
| Платформа | Холодный старт | Лимит бинарника | Цена | Сложность |
|---|---|---|---|---|
| AWS Lambda | 1-2 сек | 250 МБ (ZIP) | За вызовы + память | Средняя |