Tüm Yazılar
KategoriBackend
Okuma Süresi
21 dk
Yayın Tarihi
...
Kelime Sayısı
1.629kelime

Kahveni hazırla - bu içerikli bir makale!

Swift on Linux, SwiftNIO temelleri, Vapor vs Hummingbird karşılaştırması, veritabanı entegrasyonu, Docker deployment ve client-server model paylaşımı.

Server-Side Swift Ekosistemi: Vapor, Hummingbird ve Swift on Server

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

  1. Swift on Linux
  2. SwiftNIO Temelleri
  3. Vapor vs Hummingbird
  4. Veritabanı Entegrasyonu
  5. Structured Concurrency on Server
  6. Docker ve Deployment
  7. AWS Lambda ile Serverless Swift
  8. Client-Server Model Paylaşımı
  9. Monitoring ve Logging
  10. Performance Benchmarks

Swift on Linux {#swift-linux}

Swift, Ubuntu, Amazon Linux ve CentOS'ta resmi olarak desteklenir:

bash
1# Ubuntu'da Swift kurulumu
2wget https://download.swift.org/swift-5.9.2-release/ubuntu2204/swift-5.9.2-RELEASE/swift-5.9.2-RELEASE-ubuntu22.04.tar.gz
3tar xzf swift-5.9.2-RELEASE-ubuntu22.04.tar.gz
4export PATH=$PWD/swift-5.9.2-RELEASE-ubuntu22.04/usr/bin:$PATH
5swift --version

Platform 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 NIO
2 
3// Basit echo server
4let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
5let bootstrap = ServerBootstrap(group: group)
6 .childChannelInitializer { channel in
7 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 = ByteBuffer
17 typealias OutboundOut = ByteBuffer
18 
19 func channelRead(context: ChannelHandlerContext, data: NIOAny) {
20 // Gelen veriyi aynen geri gönder
21 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 server
2import Hummingbird
3 
4let app = HBApplication(configuration: .init(address: .hostname("0.0.0.0", port: 8080)))
5app.router.get("/hello") { _ in
6 "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 MongoKitten
12let 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/await
2func 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: recommendations
11 )
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 image
2FROM swift:5.9-jammy as build
3WORKDIR /app
4COPY Package.* ./
5RUN swift package resolve
6COPY . .
7RUN swift build -c release --static-swift-stdlib
8 
9FROM ubuntu:22.04
10RUN 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 8080
13CMD ["App", "serve", "--hostname", "0.0.0.0", "--port", "8080"]
yaml
1# docker-compose.yml
2version: '3.8'
3services:
4 app:
5 build: .
6 ports: ["8080:8080"]
7 environment:
8 - DB_HOST=db
9 - DATABASE_URL=postgres://vapor:secret@db:5432/myapp
10 depends_on: [db]
11 db:
12 image: postgres:16-alpine
13 environment:
14 POSTGRES_USER: vapor
15 POSTGRES_PASSWORD: secret
16 POSTGRES_DB: myapp
17 volumes: ["pgdata:/var/lib/postgresql/data"]
18volumes:
19 pgdata:

AWS Lambda ile Serverless Swift {#lambda}

swift
1import AWSLambdaRuntime
2 
3@main
4struct 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 package
2// iOS app ve Vapor backend aynı model'leri kullanır
3public struct CreateOrderRequest: Codable, Sendable {
4 public let items: [OrderItem]
5 public let shippingAddress: Address
6 
7 public struct OrderItem: Codable, Sendable {
8 public let productId: UUID
9 public let quantity: Int
10 }
11 
12 public struct Address: Codable, Sendable {
13 public let street: String
14 public let city: String
15 public let country: String
16 }
17}

Monitoring ve Logging {#monitoring}

swift
1import Logging
2 
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 entegrasyonu

Error Handling Stratejileri {#error-handling}

Server-side Swift'te hata yonetimi, production uygulamalarinda kritik oneme sahiptir:

swift
1// Custom error tipi
2enum AppError: AbortError {
3 case userNotFound
4 case invalidInput(String)
5 case databaseError(String)
6 case unauthorized
7 case rateLimited
8 
9 var status: HTTPResponseStatus {
10 switch self {
11 case .userNotFound: return .notFound
12 case .invalidInput: return .badRequest
13 case .databaseError: return .internalServerError
14 case .unauthorized: return .unauthorized
15 case .rateLimited: return .tooManyRequests
16 }
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 middleware
31struct 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 response
41 } 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 response
47 }
48 }
49}
50 
51struct ErrorResponse: Content {
52 let error: Bool
53 let reason: String
54}

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 monitoring
2import Metrics
3import Prometheus
4 
5// Prometheus metrics
6let requestCounter = Counter(label: "http_requests_total", dimensions: [("method", ""), ("path", "")])
7let requestDuration = Timer(label: "http_request_duration_seconds")
8 
9// Middleware'de kullanim
10struct 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_000
21 requestDuration.record(duration)
22 
23 return response
24 }
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)

Etiketler

#server-side-swift#vapor#hummingbird#swift-nio#linux#docker#backend
Muhittin Çamdalı

Muhittin Çamdalı

Senior iOS Developer

12+ yıllık deneyime sahip iOS Developer. Swift, SwiftUI ve modern iOS mimarileri konusunda uzman. Apple platformlarında performanslı ve kullanıcı dostu uygulamalar geliştiriyorum.

iOS Geliştirme Haberleri

Haftalık Swift tips, SwiftUI tricks ve iOS best practices. Spam yok, sadece değerli içerik.

Gizliliğinize saygı duyuyoruz. İstediğiniz zaman abonelikten çıkabilirsiniz.

Paylaş

Bunu da begenebilirsiniz