Почему Swift — это не только мобильная разработка?
Когда слышишь «Swift», первая ассоциация — iOS-приложения. Но в последние годы Swift уверенно шагает на серверную сторону. И это не просто хайп: Apple активно развивает экосистему, а сообщество создаёт мощные фреймворки. Если вы уже пишете на Swift под iOS и хотите расширить горизонты — микросервисы на Swift станут вашим логичным следующим шагом.
Почему именно микросервисы? Потому что это современный стандарт построения бэкенда: маленькие, независимые сервисы, которые легко масштабировать и обновлять. И Swift с его производительностью, безопасностью типов и лаконичным синтаксисом отлично для этого подходит. В этой статье мы разберём, с чего начать создание микросервисов на Swift, напишем реальный код и запустим первый сервис.
Что нужно знать перед стартом?
Для комфортного чтения вам понадобится:
- Базовое знание Swift (переменные, функции, структуры)
- Понимание HTTP и REST (хотя бы на уровне «есть запрос — есть ответ»)
- Установленный
brew(для macOS) или Docker (для Linux)
Если чего-то не хватает — не страшно, по ходу дела разберёмся.
Выбираем инструмент: Vapor — король серверного Swift
На рынке серверных фреймворков для Swift есть два главных игрока: Vapor и Kitura (от IBM). Но Kitura, увы, почти заморожен. А Vapor — активно развивается, имеет огромное комьюнити и документацию. Поэтому наш выбор — Vapor.
Vapor даёт всё из коробки: роутинг, middleware, работу с базами данных, WebSocket, асинхронность через async/await. Идеально для построения микросервисной архитектуры на Swift.
Установка Vapor Toolbox
Откройте терминал и выполните:
brew install vapor
После установки проверьте:
vapor --help
Если видите список команд — всё ок, можно создавать первый проект.
Создаём первый микросервис: Hello, World!
Наш первый микросервис будет простым: он будет принимать GET-запрос и возвращать JSON. Но мы сделаем это правильно — с архитектурой, готовой к расширению.
Шаг 1. Создаём проект
vapor new HelloMicroservice --template=auth
cd HelloMicroservice
Флаг --template=auth добавит базовую структуру с аутентификацией. Для микросервиса это хорошая практика — сразу закладывать безопасность.
Шаг 2. Структура проекта
После создания вы увидите такую структуру:
HelloMicroservice/
├── Sources/
│ ├── App/
│ │ ├── Controllers/
│ │ ├── Models/
│ │ └── configure.swift
│ └── Run/
│ └── main.swift
├── Tests/
├── Dockerfile
└── Package.swift
Обратите внимание на Dockerfile — это уже готовый шаблон для контейнеризации. Микросервисы без Docker — как пицца без сыра.
Шаг 3. Пишем первый эндпоинт
Откроем Sources/App/Controllers/UserController.swift (если его нет — создадим). Добавим простой метод:
import Vapor
struct HealthController: RouteCollection {
func boot(routes: RoutesBuilder) throws {
let health = routes.grouped("api", "health")
health.get(use: checkHealth)
}
@Sendable
func checkHealth(req: Request) async throws -> HTTPStatus {
return .ok
}
}
Это классический health-check — основа любого микросервиса. Теперь зарегистрируем его в configure.swift:
// в конце функции configure
try app.register(collection: HealthController())
Шаг 4. Запускаем и тестируем
vapor run
Откройте браузер или терминал:
curl http://localhost:8080/api/health
# Ответ: 200 OK
Поздравляю! Вы только что запустили свой первый микросервис на Swift.
Добавляем реальную логику: микросервис заметок
Теперь сделаем что-то полезное — микросервис для хранения заметок. Это покажет, как работать с базой данных и моделями.
Модель данных
Создадим модель Note:
import Fluent
import Vapor
final class Note: Model, Content {
static let schema = "notes"
@ID(key: .id)
var id: UUID?
@Field(key: "title")
var title: String
@Field(key: "content")
var content: String
@Timestamp(key: "created_at", on: .create)
var createdAt: Date?
init() { }
init(id: UUID? = nil, title: String, content: String) {
self.id = id
self.title = title
self.content = content
}
}
Обратите внимание: мы используем Fluent — ORM от Vapor. Он работает с PostgreSQL, MySQL, SQLite. Для микросервиса на старте идеально подойдёт SQLite (не нужно поднимать базу данных).
CRUD-контроллер
Создадим NoteController.swift:
import Vapor
import Fluent
struct NoteController: RouteCollection {
func boot(routes: RoutesBuilder) throws {
let notes = routes.grouped("api", "notes")
notes.get(use: index)
notes.post(use: create)
notes.delete(":noteID", use: delete)
}
@Sendable
func index(req: Request) async throws -> [Note] {
try await Note.query(on: req.db).all()
}
@Sendable
func create(req: Request) async throws -> Note {
let note = try req.content.decode(Note.self)
try await note.save(on: req.db)
return note
}
@Sendable
func delete(req: Request) async throws -> HTTPStatus {
guard let note = try await Note.find(req.parameters.get("noteID"), on: req.db) else {
throw Abort(.notFound)
}
try await note.delete(on: req.db)
return .noContent
}
}
Регистрируем в configure.swift так же, как HealthController. Теперь у нас есть работающий CRUD для заметок.
Контейнеризация: Docker для микросервиса на Swift
Микросервисы обязаны жить в контейнерах. Vapor уже создал Dockerfile, но давайте посмотрим на него и немного донастроим:
# ================================
# Build stage
# ================================
FROM swift:5.9 AS build
WORKDIR /app
COPY . .
RUN swift build --configuration release
# ================================
# Run stage
# ================================
FROM