ایک ڈویلپر نے ایک انٹرنل ٹول میں REST API کو tRPC سے تبدیل کرنے میں دو ہفتے صرف کیے۔
یہ تبدیلی کیوں اہم تھی
پرانے اسٹیک (stack) کی وجہ سے ہمیں ایک DTO، ایک ویلیڈیٹر (validator)، اور فرنٹ اینڈ کے لیے TypeScript ٹائپس کا ایک الگ سیٹ برقرار رکھنا پڑتا تھا۔ اگر بیک اینڈ کے کسی فیلڈ کا نام تبدیل کیا جاتا، تو API پھر بھی 200 ریٹرن کرتی، UI رینڈر ہوتا رہتا، اور بگ صرف "undefined" ویلیوز کی صورت میں نظر آتا۔ ٹیم کے کسی بھی رکن سے پہلے ایک کسٹمر نے اس مسئلے کو پکڑ لیا۔ REST کنٹریکٹس نے مسئلے کو چھپا دیا تھا، اور اضافی فائلوں نے ایسی مینٹیننس کا بوجھ بڑھا دیا جس کا کوئی فائدہ نہیں ہوا۔
REST سیٹ اپ کیسا نظر آتا تھا
- OpenAPI spec – ایک اسٹیٹک فائل جو اینڈ پوائنٹس (endpoints) کی وضاحت کرتی تھی لیکن کبھی بھی 'source of truth' کے طور پر کام نہیں کرتی تھی۔
- Client SDK generation step – ایک CI جاب جو JavaScript ریپر (wrapper) تیار کرتی تھی۔
- Postman collection – ایک مشترکہ ٹیسٹنگ آرٹیفیکٹ (artifact) جسے کوئی استعمال نہیں کرتا تھا۔
- Manual TypeScript interfaces – ہاتھ سے لکھے گئے ٹائپس جنہیں سرور کے ساتھ ہم آہنگ (in sync) رکھنا پڑتا تھا۔
API میں ہر تبدیلی کم از کم ان میں سے تین آرٹیفیکٹس، ویلیڈیٹر اور کسی بھی ڈاؤن اسٹریم (downstream) fetch کالز کو متاثر کرتی تھی۔ یہ عمل غلطیوں کا شکار اور سست تھا۔
tRPC نے کوڈ بیس کو کیسے کم کیا
tRPC الگ کنٹریکٹ فائل کے ضرورت کو ختم کر دیتا ہے۔ سرور ایک router type ایکسپورٹ کرتا ہے؛ کلائنٹ اسی ٹائپ کو امپورٹ کرتا ہے۔ اگر بیک اینڈ کے کسی فیلڈ کا نام تبدیل کیا جائے، تو ایڈیٹر فوری طور پر غلطی (mismatch) کی نشاندہی کر دیتا ہے—اس کے لیے کوڈ چلانے یا کسی فیل شدہ ریکویسٹ کی ضرورت نہیں ہوتی۔ ڈویلپر نے درج ذیل چیزیں نکال دیں:
- OpenAPI spec فائل۔
- Client SDK generation step۔
- غیر استعمال شدہ Postman collection۔
- مینوئل TypeScript interfaces کا فولڈر۔
ریپوزٹری (repo) زیادہ ہلکی ہو گئی، اور فیڈ بیک ڈیپلائمنٹ کے بجائے ڈویلپمنٹ کے دوران ہی ملنے لگا۔
tRPC کی حدود
tRPC صرف تب کام کرتا ہے جب دونوں اطراف TypeScript استعمال کر رہے ہوں۔ یہ درج ذیل صورتوں میں ناکام رہتا ہے:
- موبائل ٹیم Swift یا Kotlin استعمال کر رہی ہو۔
- API کو بیرونی پارٹنرز (external partners) استعمال کرنا چاہتے ہوں۔
- آپ کو ایک پبلک اور لینگویج ایگنوستک (language-agnostic) انٹرفیس کی ضرورت ہو۔
مائیگریشن کے لیے درحقیقت کیا ضروری تھا
دو ہفتوں کی یہ کوشش محض کاپی اور پیسٹ سے کہیں زیادہ تھی۔ ڈویلپر کو یہ کرنا پڑا:
- tRPC کے کلائنٹ فنکشنز استعمال کرنے کے لیے ہر
fetchکال کو دوبارہ لکھنا۔ - ایرر ہینڈلنگ (error-handling) لاجک کو ایڈجسٹ کرنا۔
- ان UI کمپوننٹس کو اپ ڈیٹ کرنا جو خام HTTP رسپانسز (raw HTTP responses) سے منسلک لوڈنگ اور ری ٹرائی (retry) اسٹیٹس پر انحصار کرتے تھے۔
آگے بڑھنے سے پہلے پوچھنے والے سوالات
- کیا فرنٹ اینڈ اور بیک اینڈ دونوں TypeScript استعمال کرتے ہیں؟ ایک مشترکہ ٹائپ سسٹم کے بغیر، tRPC اپنا اصل فائدہ کھو دیتا ہے۔
- کیا دونوں اطراف کی ذمہ داری ایک ہی ٹیم پر ہے؟ ذمہ داریوں میں فرق (ownership gaps) دوبارہ کنٹریکٹ ڈرفٹ (contract drift) کا باعث بن سکتا ہے۔
- کیا آپ کسی حقیقی بگ کو ٹھیک کر رہے ہیں یا محض کسی ٹرینڈ کے پیچھے بھاگ رہے ہیں؟ پیداواری صلاحیت (productivity) میں اضافہ حقیقی ہے، لیکن اسے کسی موجودہ مسئلے (pain point) کو حل کرنا چاہیے۔
2025 کے لیے ایک ہائبرڈ طریقہ کار
بہت سی ٹیمیں دونوں اسٹیکس کو چلا کر ایک بہترین توازن (sweet spot) حاصل کر لیتی ہیں:
- انٹرنل ایپلی کیشن لیئرز کے لیے tRPC جہاں کوڈ بیس مکمل طور پر TypeScript ہے اور ایک ہی ٹیم سرور اور کلائنٹ کی مالک ہے۔
- ویب ہکس (webhooks)، پبلک APIs، اور پارٹنر انٹیگریشنز کے لیے REST جہاں لینگویج ایگنوستک رسائی کی ضرورت ہو۔
ہر سطح کے لیے صحیح ٹول کا استعمال انٹرنل ڈویلپمنٹ کو تیز رکھتا ہے جبکہ بیرونی صارفین کے لیے ضروری کھلے پن (openness) کو بھی برقرار رکھتا ہے۔
حاصلِ کلام: REST کو tRPC سے تبدیل کرنے سے ڈپلیکیٹ کنٹریکٹ آرٹیفیکٹس ختم ہو سکتے ہیں اور ایڈیٹنگ کے وقت ہی بگ سامنے آ سکتے ہیں، لیکن اس کا فائدہ صرف تب ہی ہوتا ہے جب پورا اسٹیک TypeScript شیئر کرتا ہو اور ٹیم مائیگریشن کی لاگت برداشت کرنے کی صلاحیت رکھتی ہو۔ ایک مخلوط حکمت عملی (mixed strategy) آپ کو غیر TypeScript صارفین کو الگ کیے بغیر فوائد حاصل کرنے کی اجازت دیتی ہے۔
