Introdução: Por que Swift é uma plataforma madura para microsserviços
Tradicionalmente, Swift é associado ao desenvolvimento para iOS e macOS. No entanto, com o surgimento dos frameworks Vapor e Hummingbird, além da biblioteca SwiftNIO, Swift tornou-se uma linguagem completa para desenvolvimento no servidor. A arquitetura de microsserviços em Swift não é apenas uma tendência, mas uma escolha pragmática para projetos onde desempenho, segurança de tipos e integração nativa com o ecossistema Apple são importantes.
Neste artigo, abordaremos aspectos avançados da construção de microsserviços em Swift: desde a escolha do transporte até a implantação em Docker. Os exemplos de código são voltados para Swift 5.9+ e macOS/Linux.
Arquitetura de microsserviço em Swift: do monolito ao sistema distribuído
Escolha do framework: Vapor vs Hummingbird
Para soluções de produção, recomenda-se Vapor 4 (estável, comunidade extensa) ou Hummingbird (leve, minimalista). Ambos são construídos sobre SwiftNIO.
A estrutura básica de um microsserviço em Vapor inclui:
- Routes (rotas) — tratamento de requisições HTTP.
- Controllers (controladores) — lógica de negócios.
- Services (serviços) — módulos isolados (banco de dados, APIs externas).
- Models (modelos) — Fluent ORM para trabalhar com BD.
// Exemplo de estrutura básica de microsserviço em Vaporimport Vapor
func routes(_ app: Application) throws { let orderController = OrderController() app.get("orders", ":id", use: orderController.getOrder) app.post("orders", use: orderController.createOrder)}
final class OrderController { func getOrder(req: Request) async throws -> Order { let orderID = try req.parameters.require("id", as: UUID.self) return try await Order.find(orderID, on: req.db) ?? Abort(.notFound) }}Protocolos e Injeção de Dependência
Para baixo acoplamento, use protocolos. Isso simplifica testes e substituição de componentes.
protocol PaymentServiceProtocol { func processPayment(amount: Double, currency: String) async throws -> PaymentResult}
final class StripeService: PaymentServiceProtocol { func processPayment(amount: Double, currency: String) async throws -> PaymentResult { // Lógica de chamada da API Stripe }}
// Registro no contêiner DI do Vaporapp.services.register(PaymentServiceProtocol.self) { _ in StripeService() }Comunicação avançada: gRPC e Async/Await
Por que gRPC em vez de REST
Para microsserviços internos, gRPC é preferível ao REST devido a:
- Tipagem estrita via Protocol Buffers.
- Protocolo binário (menos tráfego).
- Suporte nativo a streaming.
Swift suporta gRPC através da biblioteca grpc-swift. Exemplo de definição de serviço:
// user.protoservice UserService { rpc GetUser (UserRequest) returns (UserResponse); rpc ListUsers (Empty) returns (stream UserResponse);}
message UserRequest { string user_id = 1;}
message UserResponse { string id = 1; string name = 2; string email = 3;}Geração de código Swift:
protoc --swift_out=. --grpc-swift_out=. user.protoImplementação do servidor em Swift:
import GRPCimport NIO
final class UserServiceImpl: UserServiceProvider { func getuser(request: UserRequest, context: StatusOnlyCallContext) -> EventLoopFuture { let user = UserResponse.with { $0.id = request.userID $0.name = "John Doe" $0.email = "john@example.com" } return context.eventLoop.makeSucceededFuture(user) }} Async/Await em microsserviços
Swift 5.5+ trouxe