Python Programming

بناء واجهات برمجة تطبيقات GraphQL في الوقت الفعلي باستخدام FastAPI وStrawberry لجلب البيانات الديناميكي

يتطلب مشهد تطوير الويب الحديث تطبيقات لا تكون سريعة فحسب، بل تكون أيضًا مستجيبة لحالات البيانات المتغيرة في الوقت الفعلي. وعلى الرغم من أن واجهات برمجة تطبيقات REST كانت هي المعيار لسنوات طويلة، فإن صعود GraphQL قد أحدث ثورة في طريقة جلب العملاء للبيانات، مما يسمح باستعلامات دقيقة وتقليل جلب البيانات الزائدة. ومع ذلك، فإن دمج GraphQL مع القدرات في الوقت الفعلي - مثل تحديثات الدردشة المباشرة أو تدفقات سوق الأسهم - غالبًا ما يقدم تعقيدًا كبيرًا. في هذا المنشور، سنستكشف كيفية الاستفادة من سرعة FastAPI وأمان الأنواع في Strawberry لبناء واجهة برمجة تطبيقات GraphQL قوية وفي الوقت الفعلي تتفوق في جلب البيانات الديناميكي.

لماذا FastAPI وStrawberry؟

تشتهر FastAPI بأدائها العالي ودعمها الأصلي للبرمجة غير المتزامنة، مما يجعلها إطار عمل مثاليًا لبناء واجهات برمجة تطبيقات ذات التزامن عالي. في الوقت نفسه، تعد Strawberry مكتبة GraphQL حديثة للغة بايثون تركز على أمان الأنواع وتجربة المطور. وعلى عكس المكتبات الأقدم، تتكامل Strawberry بسلاسة مع تلميحات الأنواع في بايثون وتدعم المحللات غير المتزامنة (async resolvers) بشكل افتراضي.

عند دمجهما، تقدم هاتان المكتبتان معًا مجموعة قوية. تتولى FastAPI التعامل مع اتصالات WebSocket المطلوبة للاشتراكات في الوقت الفعلي، بينما تدير Strawberry تعريف مخطط GraphQL وحل الاستعلامات. يسمح هذا الفصل بين المسؤوليات للمطورين بالتركيز على المنطق بدلاً من الأعمال الأساسية، مما يضمن بقاء واجهة برمجة التطبيقات قابلة للصيانة مع توسعها.

إعداد بيئة المشروع

قبل الغوص في الكود، تأكد من تثبيت الاعتماديات اللازمة. ستحتاج إلى FastAPI وStrawberry GraphQL، ودعم WebSocket لـ Strawberry، وخادم ASGI مثل Uvicorn.

pip install fastapi strawberry-graphql uvicorn [all]

جلبت هذه العملية تثبيت المنطق الأساسي لـ GraphQL، ودعم غير المتزامن، والأدوات اللازمة لتشغيل الخادم. سنبدأ بتحديد نموذج البيانات الخاص بنا. نظرًا لأننا نتعامل مع بيانات في الوقت الفعلي، فسوف نقوم بمحاكاة تدفق لأسعار الأسهم.

تحديد المخطط باستخدام Strawberry

يُعد المخطط الخاص بأي واجهة برمجة تطبيقات GraphQL هو جوهرها. تسمح Strawberry لنا بتعريف الأنواع والعمليات (mutations) والاستعلامات باستخدام فئات بايثون. لقدرات الوقت الفعلي، نستخدم strawberry.subscription لتحديد الاشتراكات.

import strawberry
import asyncio
from typing import AsyncGenerator
from datetime import datetime

@strawberry.type
class StockUpdate:
    symbol: str
    price: float
    timestamp: datetime
    volatility: str

class Query:
    @strawberry.field
    def current_price(self, symbol: str) -> str:
        return f"جاري جلب سعر {symbol}..."

@strawberry.subscription
async def stock_updates(self, symbol: str) -> AsyncGenerator[StockUpdate, None]:
    """
    اشتراك في الوقت الفعلي يصدر تحديثات لأسعار الأسهم.
    """
    while True:
        price = round(100 + (await asyncio.sleep(1)) * 10, 2)
        update = StockUpdate(
            symbol=symbol,
            price=price,
            timestamp=datetime.utcnow(),
            volatility="high" if price > 150 else "low"
        )
        yield update

في هذا المثال، نحدد اشتراك stock_updates. يقوم بإرجاع البيانات بشكل غير متزامن، مما يحاكي بثًا مباشرًا. يمكن للعميل الاشتراك في رمز سهم معين وتلقي التحديثات دون الحاجة إلى استعلام الخادم (polling)، مما يقلل بشكل كبير من زمن الانتقال (latency) وحمل الخادم.

التكامل مع FastAPI والتعامل مع WebSockets

لتقديم هذا المخطط، نقوم بتغليفه في تطبيق FastAPI. يبسط GraphQLRouter الخاص بـ FastAPI توجيه استعلامات GraphQL والعمليات والاشتراكات إلى نقطة نهاية واحدة.

from fastapi import FastAPI
from strawberry.fastapi import GraphQLRouter

# تعريف المخطط
schema = strawberry.Schema(query=Query, subscription=Subscription)

# إنشاء تطبيق FastAPI
app = FastAPI(
    title="واجهة برمجة تطبيقات GraphQL في الوقت الفعلي",
    description="بناء جلب البيانات الديناميكي باستخدام FastAPI وStrawberry",
)

# تثبيت موجه GraphQL
graphql_app = GraphQLRouter(schema)
app.include_router(graphql_app, prefix="/graphql")

# الخادم جاهز الآن للتعامل مع طلبات GET للاستعلامات واتصالات WS للاشتراكات.

عند تشغيل هذا التطبيق باستخدام uvicorn main:app --reload، تقوم FastAPI بترقية اتصالات HTTP القياسية إلى اتصالات WebSocket تلقائيًا عندما يطلب العميل اشتراكًا. هذا يسمح للخادم بدفع البيانات إلى العميل بمجرد توفرها.

التحسين لجلب البيانات الديناميكي

إحدى المزايا الرئيسية لهذه البنية هي قدرتها على التعامل مع الطلبات الديناميكية. نظرًا لأن العميل يطلب الحقول التي يحتاجها بالضبط، فإن الخادم يحل فقط ما هو ضروري. في سيناريو يحتاج فيه لوحة المعلومات إلى عرض 50 سهمًا مختلفًا، يمكن للعميل طلب تحديث دفعة لتلك الرموز المحددة، ويمكن لمنطق الاشتراك تصفية التحديثات أو توجيهها وفقًا لذلك.

علاوة على ذلك، فإن الطبيعة غير المتزامنة لكل من FastAPI وStrawberry تضمن أن العمليات المرتبطة بـ I/O، مثل استعلامات قاعدة البيانات أو المكالمات الخارجية لواجهة برمجة التطبيقات، لا تعطل حلقة الأحداث (event loop). هذا أمر بالغ الأهمية للتطبيقات في الوقت الفعلي حيث قد يتم إنشاء آلاف الاتصالات المتزامنة في وقت واحد.

الخاتمة

لم يعد بناء واجهات برمجة تطبيقات GraphQL في الوقت الفعلي حكرًا على إعدادات Node.js المعقدة. من خلال الاستفادة من نظام بايثون الحديث مع FastAPI وStrawberry، يمكن للمطورين إنشاء حلول عالية الأداء وآمنة الأنواع وقابلة للتوسع. يمنحك هذا المزيج القدرة على تقديم قدرات جلب البيانات الديناميكي التي تعزز تجربة المستخدم مع الحفاظ على بنية الخلفية نظيفة وقابلة للصيانة. سواء كنت تبني لوحة معلومات مالية، أو محرر تعاوني، أو تطبيق دردشة مباشر، فإن هذه المجموعة توفر الأساس الذي تحتاجه للنجاح.

Share: