Microservices en Swift : architecture et pratique pour les pros

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : Pourquoi Swift est une plateforme mature pour les microservices

Traditionnellement, Swift est associé au développement iOS et macOS. Cependant, avec l'émergence des frameworks Vapor et Hummingbird, ainsi que de la bibliothèque SwiftNIO, Swift est devenu un langage à part entière pour le développement côté serveur. L'architecture de microservices en Swift n'est pas seulement une tendance, mais un choix pragmatique pour les projets où la performance, la sécurité des types et l'intégration native avec l'écosystème Apple sont importantes.

Dans cet article, nous aborderons les aspects avancés de la construction de microservices en Swift : du choix du transport au déploiement dans Docker. Les exemples de code sont destinés à Swift 5.9+ et macOS/Linux.



Architecture d'un microservice en Swift : du monolithe au système distribué

Choix du framework : Vapor vs Hummingbird

Pour les solutions de production, Vapor 4 (stable, large communauté) ou Hummingbird (léger, minimaliste) sont recommandés. Les deux sont construits sur SwiftNIO.

La structure de base d'un microservice sur Vapor comprend :

  • Routes (itinéraires) — traitement des requêtes HTTP.
  • Controllers (contrôleurs) — logique métier.
  • Services (services) — modules isolés (base de données, API externes).
  • Models (modèles) — Fluent ORM pour travailler avec la base de données.


// Exemple de structure de base d'un microservice sur 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) }}


Protocoles et Injection de Dépendances

Pour un couplage faible, utilisez des protocoles. Cela simplifie les tests et le remplacement des composants.

protocol PaymentServiceProtocol {    func processPayment(amount: Double, currency: String) async throws -> PaymentResult}

final class StripeService: PaymentServiceProtocol { func processPayment(amount: Double, currency: String) async throws -> PaymentResult { // Logique d'appel à l'API Stripe }}

// Enregistrement dans le conteneur DI de Vaporapp.services.register(PaymentServiceProtocol.self) { _ in StripeService() }


Communication avancée : gRPC et Async/Await

Pourquoi gRPC plutôt que REST

Pour les microservices internes, gRPC est préférable à REST en raison de :

  • Typage strict via Protocol Buffers.
  • Protocole binaire (moins de trafic).
  • Support intégré du streaming.

Swift prend en charge gRPC via la bibliothèque grpc-swift. Exemple de définition de service :



// 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;}


Génération du code Swift :

protoc --swift_out=. --grpc-swift_out=. user.proto


Implémentation du serveur en 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 dans les microservices

Swift 5.5+ a apporté

Blogs

Book Recommendations