مقدمة في الخدمات المصغرة باستخدام Swift
عالم تطوير الأجهزة المحمولة والخوادم يتغير بسرعة. إذا كان Swift سابقًا يرتبط حصريًا بتطبيقات iOS و macOS، فإنه اليوم يخرج بثقة إلى جانب الخادم. بنية الخدمات المصغرة باستخدام Swift ليست مجرد موضة، بل هي أداة قوية لإنشاء أنظمة قابلة للتوسع، ومتسامحة مع الأخطاء، وسهلة الصيانة. في هذه المقالة، سنشرح المبادئ الأساسية لبناء الخدمات المصغرة باستخدام Swift، وسنستعرض أمثلة عملية باستخدام إطار العمل Vapor، ونناقش أفضل الممارسات لمطوري iOS/macOS.
لماذا Swift للخدمات المصغرة؟
Swift هي لغة حديثة وآمنة وسريعة. استخدامها على الخادم يوفر عددًا من المزايا التي لا يمكن إنكارها:
- الأداء: يتم ترجمة Swift إلى كود أصلي، مما يضمن سرعة تنفيذ عالية، مماثلة لـ C++ و Rust.
- أمان الأنواع: الكتابة الصارمة والأنواع الاختيارية (Optionals) تقلل من عدد أخطاء وقت التشغيل.
- قاعدة كود موحدة: إذا كنت تكتب بالفعل بلغة Swift لنظام iOS، يمكنك استخدام نفس المهارات والمكتبات للجزء الخادم، مما يبسط الصيانة وإعادة الهيكلة.
- النظام البيئي لـ Vapor: إطار العمل الخادم الأكثر شيوعًا لـ Swift، والذي يوفر كل ما هو ضروري لإنشاء REST API، والعمل مع قواعد البيانات و WebSockets.
هندسة الخدمات المصغرة باستخدام Swift
تفترض بنية الخدمات المصغرة تقسيم التطبيق إلى خدمات صغيرة ومستقلة وقابلة للنشر بشكل منفصل. كل خدمة مسؤولة عن منطق أعمالها الخاص وتتفاعل مع الخدمات الأخرى عبر API (غالبًا HTTP/REST أو gRPC).
المكونات الأساسية
- API Gateway: نقطة دخول واحدة للعملاء (مثل تطبيق iOS). يقوم بتوجيه الطلبات إلى الخدمات المصغرة المناسبة.
- الخدمات: كل خدمة هي تطبيق Vapor منفصل، يعالج الجزء الخاص به من المنطق (مثل خدمة المستخدمين، خدمة الطلبات، خدمة الإشعارات).
- قاعدة البيانات: يمكن أن يكون لكل خدمة مصغرة قاعدة بيانات خاصة بها (أو قاعدة بيانات مشتركة، لكن هذا ينتهك مبدأ العزل).
- قوائم انتظار الرسائل: للتفاعل غير المتزامن بين الخدمات (مثل RabbitMQ أو Kafka).
مثال لخدمة مصغرة بسيطة باستخدام Vapor
لنفكر في خدمة مصغرة أساسية لإدارة المستخدمين. ستستقبل طلبات إنشاء وجلب المستخدمين.
الخطوة 1: إنشاء المشروع
vapor new UserService --template=apicd UserServicevapor updateالخطوة 2: تعريف النموذج
import Vaporimport Fluent
final class User: Model, Content { static let schema = "users" @ID(key: .id) var id: UUID? @Field(key: "name") var name: String @Field(key: "email") var email: String init() {} init(id: UUID? = nil, name: String, email: String) { self.id = id self.name = name self.email = email }}الخطوة 3: إنشاء المتحكم
import Vapor
struct UserController: RouteCollection { func boot(routes: RoutesBuilder) throws { let users = routes.grouped("users") users.post(use: create) users.get(use: index) } func create(req: Request) throws -> EventLoopFuture<User> { let user = try req.content.decode(User.self) return user.save(on: req.db).map { user } } func index(req: Request) throws -> EventLoopFuture<[User]> { return User.query(on: req.db).all() }}الخطوة 4: التسجيل في configure.swift
import Vapor
public func configure(_ app: Applicatio