GraphQL ویڈیو ڈسکوری API بنانا
جب ہمارا ویڈیو ڈیٹا بیس لاکھوں ریکارڈز تک پہنچ گیا، تو ہماری API رکاوٹ (bottleneck) بن گئی۔
ایک ہی اسکرین پر ٹرینڈنگ ویڈیوز، چینل کی تفصیلات، ٹیگز، ویوز کی تعداد اور سفارشات (recommendations) دکھانے کے لیے پانچ مختلف REST کالز کی ضرورت ہوتی تھی۔ سست کنکشن پر موجود موبائل صارفین کو محض ایک پیج لوڈ کرنے کے لیے 30 درخواستیں بھیجنی پڑتی تھیں۔
GraphQL اس مسئلے کو حل کرتا ہے۔ کلائنٹ ایک ہی درخواست میں بالکل وہی چیز مانگتا ہے جس کی اسے ضرورت ہوتی ہے۔
میں نے Strawberry اور FastAPI کا استعمال کرتے ہوئے ایک پروڈکشن ویڈیو ڈسکوری API بنائی۔ میں نے اسے اس طرح کیا:
Strawberry کیوں؟
میں نے Graphene اور Ariadne کا تجربہ کیا، لیکن Strawberry ان وجوہات کی بنا پر جیت گیا:
• Type hints ہی اسکیما ہیں۔ آپ Python کوڈ لکھتے ہیں، اور Strawberry GraphQL ٹائپس بناتا ہے۔ دستی طور پر سنکنگ (syncing) کرنے کی ضرورت نہیں ہوتی۔ • یہ async-native ہے۔ یہ API کو ایونٹ لوپ (event loop) کو بلاک کیے بغیر بہت سی درخواستوں کو سنبھالنے کی اجازت دیتا ہے۔ • FastAPI کے ساتھ انٹیگریشن بالکل ہموار ہے۔ GraphQL اینڈ پوائنٹ موجودہ REST روٹس کے بالکل ساتھ ہوتا ہے۔ • بلٹ ان DataLoader۔ یہ ٹول N+1 کے مسئلے کو فوری طور پر حل کر دیتا ہے۔
ڈیٹا اسٹیک
ڈیٹا ایک SQLite ڈیٹا بیس میں موجود ہے جسے ایک PHP سائٹ کے ذریعے مینیج کیا جاتا ہے۔ میں تیز رفتار فل ٹیکسٹ سرچ کے لیے SQLite FTS5 کا استعمال کرتا ہوں۔
Python سروس اس ڈیٹا بیس کو ریڈ اونلی (read-only) لیئر کے طور پر پڑھتی ہے۔ اس سے یہ یقینی بنتا ہے کہ معلومات کا صرف ایک ہی مستند ذریعہ (source of truth) ہو۔
سرچ کے تجربے کو بہتر بنانے کے لیے، میں FTS5 کی ریلیوینس اسکورز کو پاپولرٹی سگنل کے ساتھ ملا دیتا ہوں۔ یہ کسی ایک وائرل ویڈیو کو تمام دیگر سرچ نتائج پر حاوی ہونے سے روکتا ہے۔
N+1 کے مسئلے کا حل
GraphQL میں ایک عام مسئلہ N+1 کا مسئلہ ہے۔ اگر آپ 20 ویڈیوز حاصل کرتے ہیں اور پھر ہر ایک کے لیے چینل حاصل کرتے ہیں، تو ایک سادہ API ڈیٹا بیس پر 21 کوئریز چلائے گی۔
DataLoader اسے بیچنگ (batching) کے ذریعے ٹھیک کرتا ہے۔ یہ ایک ہی وقت میں تمام چینل آئی ڈیز کو جمع کرتا ہے اور انہیں حاصل کرنے کے لیے ایک ہی کوئری چلاتا ہے۔ اس سے ہمارا کوئری ٹائم 40ms سے کم ہو کر 5ms سے بھی نیچے آ گیا۔
ڈیزائن کے اہم انتخاب
• Opaque IDs: میں آئی ڈیز کے لیے اسٹرنگز (strings) استعمال کرتا ہوں۔ اس سے کلائنٹ ایپس کو خراب کیے بغیر مستقبل میں تبدیلیاں کرنا ممکن ہوتا ہے۔ • Intentional Nullability: میں یہ طے کرتا ہوں کہ کون سے فیلڈز خالی ہو سکتے ہیں۔ اس سے کلائنٹس کو کریش ہوئے بغیر ڈیٹا کی کمی کو سنبھالنے میں مدد ملتی ہے۔ • Read-only Schema: GraphQL API ڈیٹا لکھنے (writes) کا کام نہیں کرتی۔ اس سے سیکیورٹی کے بہت سے مسائل ختم ہو جاتے ہیں۔ • Edge Caching: GraphQL ڈیفالٹ کے طور پر POST استعمال کرتا ہے، جسے کیش (cache) کرنا مشکل ہوتا ہے۔ میں Cloudflare کے ذریعے کیشنگ کی اجازت دینے کے لیے Automatic Persisted Queries (APQ) کا استعمال کرتا ہوں۔
اگر آپ بہت زیادہ کسٹم اینڈ پوائنٹس یا پیچیدہ کوئری پیرامیٹرز سے پریشان ہیں، تو یہ اسٹیک ایک بہترین آپشن ہے۔
