Swift sadece iOS/macOS için değil — Linux'ta da çalışır ve server-side development için güçlü bir ekosisteme sahip. Aynı dil, aynı tipler, client ve server'da. Bu rehberde Swift on Server ekosistemini derinlemesine inceleyeceğiz.
💡 Hızlı Not: Swift Server Work Group (SSWG), Apple sponsorluğunda server-side Swift ekosistemini yöneten resmi gruptur.
İçindekiler
- Swift on Linux
- SwiftNIO Temelleri
- Vapor vs Hummingbird
- Veritabanı Entegrasyonu
- Structured Concurrency on Server
- Docker ve Deployment
- AWS Lambda ile Serverless Swift
- Client-Server Model Paylaşımı
- Monitoring ve Logging
- Performance Benchmarks
Swift on Linux {#swift-linux}
Swift, Ubuntu, Amazon Linux ve CentOS'ta resmi olarak desteklenir:
bash
1# Ubuntu'da Swift kurulumu2wget https://download.swift.org/swift-5.9.2-release/ubuntu2204/swift-5.9.2-RELEASE/swift-5.9.2-RELEASE-ubuntu22.04.tar.gz3tar xzf swift-5.9.2-RELEASE-ubuntu22.04.tar.gz4export PATH=$PWD/swift-5.9.2-RELEASE-ubuntu22.04/usr/bin:$PATH5swift --versionPlatform Farkları
Özellik | macOS | Linux |
|---|---|---|
Foundation | Apple Foundation | swift-corelibs-foundation |
Dispatch | libdispatch | libdispatch |
Objective-C | ✅ Var | ❌ Yok |
UIKit/AppKit | ✅ Var | ❌ Yok |
Crypto | CryptoKit | swift-crypto |
async/await | ✅ | ✅ |
SwiftNIO Temelleri {#swift-nio}
SwiftNIO, Apple'ın event-driven networking framework'üdür. Netty'den ilham alır:
swift
1import NIO2 3// Basit echo server4let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)5let bootstrap = ServerBootstrap(group: group)6 .childChannelInitializer { channel in7 channel.pipeline.addHandler(EchoHandler())8 }9 .childChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1)10 11let channel = try bootstrap.bind(host: "0.0.0.0", port: 8080).wait()12print("Server running on \(channel.localAddress!)")13try channel.closeFuture.wait()14 15class EchoHandler: ChannelInboundHandler {16 typealias InboundIn = ByteBuffer17 typealias OutboundOut = ByteBuffer18 19 func channelRead(context: ChannelHandlerContext, data: NIOAny) {20 // Gelen veriyi aynen geri gönder21 context.write(data, promise: nil)22 }23 24 func channelReadComplete(context: ChannelHandlerContext) {25 context.flush()26 }27}Vapor vs Hummingbird {#vapor-vs-hummingbird}
Özellik | Vapor | Hummingbird |
|---|---|---|
Olgunluk | 2016'dan beri | 2021'den beri |
Topluluk | Büyük | Büyüyen |
ORM | Fluent (built-in) | External |
WebSocket | ✅ Built-in | ✅ Plugin |
Template | Leaf | Mustache |
Performans | Yüksek | Çok yüksek |
Boyut | Büyük framework | Minimal, modüler |
Learning curve | Orta | Düşük |
swift
1// Hummingbird minimal server2import Hummingbird3 4let app = HBApplication(configuration: .init(address: .hostname("0.0.0.0", port: 8080)))5app.router.get("/hello") { _ in6 "Hello from Hummingbird!"7}8try await app.start()Veritabanı Entegrasyonu {#database}
swift
1// PostgreSQL (Fluent + Vapor)2app.databases.use(.postgres(3 hostname: Environment.get("DB_HOST") ?? "localhost",4 port: 5432,5 username: "vapor",6 password: "secret",7 database: "myapp"8), as: .psql)9 10// MongoDB (MongoKitten)11import MongoKitten12let db = try await MongoDatabase.connect(to: "mongodb://localhost/myapp")13let users = db["users"]14let results = try await users.find(["age": ["$gte": 18]]).decode(User.self).allResults()Structured Concurrency on Server {#concurrency}
swift
1// Server-side async/await2func handleRequest(req: Request) async throws -> Response {3 async let user = fetchUser(id: req.userId)4 async let orders = fetchOrders(userId: req.userId)5 async let recommendations = fetchRecommendations(userId: req.userId)6 7 let dashboard = try await DashboardResponse(8 user: user,9 orders: orders,10 recommendations: recommendations11 )12 return Response(status: .ok, body: .init(data: try JSONEncoder().encode(dashboard)))13}Docker ve Deployment {#docker}
dockerfile
1# Multi-stage build - küçük final image2FROM swift:5.9-jammy as build3WORKDIR /app4COPY Package.* ./5RUN swift package resolve6COPY . .7RUN swift build -c release --static-swift-stdlib8 9FROM ubuntu:22.0410RUN apt-get update && apt-get install -y libcurl4 && rm -rf /var/lib/apt/lists/*11COPY --from=build /app/.build/release/App /usr/local/bin/12EXPOSE 808013CMD ["App", "serve", "--hostname", "0.0.0.0", "--port", "8080"]yaml
1# docker-compose.yml2version: '3.8'3services:4 app:5 build: .6 ports: ["8080:8080"]7 environment:8 - DB_HOST=db9 - DATABASE_URL=postgres://vapor:secret@db:5432/myapp10 depends_on: [db]11 db:12 image: postgres:16-alpine13 environment:14 POSTGRES_USER: vapor15 POSTGRES_PASSWORD: secret16 POSTGRES_DB: myapp17 volumes: ["pgdata:/var/lib/postgresql/data"]18volumes:19 pgdata:AWS Lambda ile Serverless Swift {#lambda}
swift
1import AWSLambdaRuntime2 3@main4struct MyHandler: SimpleLambdaHandler {5 func handle(_ event: APIGatewayV2Request, context: LambdaContext) async throws -> APIGatewayV2Response {6 let name = event.queryStringParameters?["name"] ?? "World"7 return APIGatewayV2Response(8 statusCode: .ok,9 body: "Hello, \(name)!"10 )11 }12}Client-Server Model Paylaşımı {#model-sharing}
swift
1// SharedModels SPM package2// iOS app ve Vapor backend aynı model'leri kullanır3public struct CreateOrderRequest: Codable, Sendable {4 public let items: [OrderItem]5 public let shippingAddress: Address6 7 public struct OrderItem: Codable, Sendable {8 public let productId: UUID9 public let quantity: Int10 }11 12 public struct Address: Codable, Sendable {13 public let street: String14 public let city: String15 public let country: String16 }17}Monitoring ve Logging {#monitoring}
swift
1import Logging2 3let logger = Logger(label: "com.myapp.server")4logger.info("Request received", metadata: ["path": "\(req.url.path)"])5logger.error("Database error", metadata: ["error": "\(error)"])6 7// Structured logging ile Grafana/ELK entegrasyonuError Handling Stratejileri {#error-handling}
Server-side Swift'te hata yonetimi, production uygulamalarinda kritik oneme sahiptir:
swift
1// Custom error tipi2enum AppError: AbortError {3 case userNotFound4 case invalidInput(String)5 case databaseError(String)6 case unauthorized7 case rateLimited8 9 var status: HTTPResponseStatus {10 switch self {11 case .userNotFound: return .notFound12 case .invalidInput: return .badRequest13 case .databaseError: return .internalServerError14 case .unauthorized: return .unauthorized15 case .rateLimited: return .tooManyRequests16 }17 }18 19 var reason: String {20 switch self {21 case .userNotFound: return "Kullanici bulunamadi"22 case .invalidInput(let detail): return "Gecersiz girdi: \(detail)"23 case .databaseError(let detail): return "Veritabani hatasi: \(detail)"24 case .unauthorized: return "Yetkiniz yok"25 case .rateLimited: return "Cok fazla istek, lutfen bekleyin"26 }27 }28}29 30// Global error middleware31struct ErrorHandlerMiddleware: AsyncMiddleware {32 func respond(to request: Request, chainingTo next: AsyncResponder) async throws -> Response {33 do {34 return try await next.respond(to: request)35 } catch let error as AppError {36 request.logger.warning("App error: \(error.reason)")37 let body = ErrorResponse(error: true, reason: error.reason)38 let response = Response(status: error.status)39 try response.content.encode(body)40 return response41 } catch {42 request.logger.error("Unexpected error: \(error)")43 let body = ErrorResponse(error: true, reason: "Beklenmeyen bir hata olustu")44 let response = Response(status: .internalServerError)45 try response.content.encode(body)46 return response47 }48 }49}50 51struct ErrorResponse: Content {52 let error: Bool53 let reason: String54}SSWG Paket Ekosistemi {#sswg-packages}
Swift Server Work Group tarafindan onaylanan ve production-ready olarak kabul edilen paketler:
Paket | Kullanim | SSWG Seviyesi |
|---|---|---|
SwiftNIO | Event-driven networking | Graduated |
AsyncHTTPClient | HTTP client | Graduated |
SwiftLog | Structured logging | Graduated |
SwiftMetrics | Monitoring metrics | Graduated |
swift-crypto | Kriptografi | Graduated |
PostgresNIO | PostgreSQL driver | Sandbox |
RediStack | Redis client | Sandbox |
MongoSwift | MongoDB driver | Sandbox |
Soto | AWS SDK for Swift | Incubating |
swift-distributed-actors | Distributed computing | Incubating |
swift
1// SwiftMetrics ile monitoring2import Metrics3import Prometheus4 5// Prometheus metrics6let requestCounter = Counter(label: "http_requests_total", dimensions: [("method", ""), ("path", "")])7let requestDuration = Timer(label: "http_request_duration_seconds")8 9// Middleware'de kullanim10struct MetricsMiddleware: AsyncMiddleware {11 func respond(to request: Request, chainingTo next: AsyncResponder) async throws -> Response {12 let startTime = DispatchTime.now()13 requestCounter.increment(dimensions: [14 ("method", request.method.rawValue),15 ("path", request.url.path)16 ])17 18 let response = try await next.respond(to: request)19 20 let duration = Double(DispatchTime.now().uptimeNanoseconds - startTime.uptimeNanoseconds) / 1_000_000_00021 requestDuration.record(duration)22 23 return response24 }25}Production Checklist {#production-checklist}
Server-side Swift uygulamasini production'a almadan once kontrol listesi:
Madde | Aciklama | Oncelik |
|---|---|---|
TLS/HTTPS | Nginx reverse proxy veya built-in TLS | Kritik |
Rate limiting | IP bazli istek siniri | Kritik |
CORS ayarlari | Izin verilen origin'leri belirle | Yuksek |
Health check | /health endpoint'i ile liveness/readiness | Yuksek |
Structured logging | JSON format, log level ayari | Yuksek |
Graceful shutdown | SIGTERM yakalama, mevcut istekleri tamamla | Orta |
Database pool | Connection pool boyutunu ayarla | Orta |
Environment config | Hassas bilgileri .env'den oku | Kritik |
Monitoring | Prometheus + Grafana veya Datadog | Yuksek |
Backup | Veritabani yedekleme stratejisi | Kritik |
Performance Benchmarks {#benchmarks}
Framework | Req/sec (JSON) | Latency p99 | Memory |
|---|---|---|---|
Vapor | 85K | 2.1ms | 45MB |
Hummingbird | 120K | 1.4ms | 25MB |
Actix (Rust) | 180K | 0.8ms | 15MB |
Express (Node) | 42K | 4.8ms | 120MB |
Django (Python) | 8K | 22ms | 180MB |
Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?
ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
Okuyucu Ödülü
Tebrikler! Bu yazıyı sonuna kadar okuduğun için sana özel bir hediyem var: **Kaynaklar:** - [Swift Server Work Group](https://www.swift.org/sswg/) - [SwiftNIO](https://github.com/apple/swift-nio) - [Hummingbird](https://github.com/hummingbird-project/hummingbird)

