एक डेवलपर ने एक इंटरनल टूल में REST API को tRPC से बदलने में दो सप्ताह बिताए।

यह बदलाव क्यों महत्वपूर्ण था

पुराने स्टैक के कारण हमें एक DTO, एक वैलिडेटर और फ्रंटएंड के लिए TypeScript टाइप्स का एक अलग सेट बनाए रखना पड़ता था। यदि बैकएंड फ़ील्ड का नाम बदल दिया जाता, तो भी API 200 रिटर्न करता था, UI रेंडर होता रहता था, और बग केवल "undefined" वैल्यू के रूप में दिखाई देता था। टीम के किसी भी सदस्य से पहले एक ग्राहक ने इस समस्या को पकड़ लिया। REST कॉन्ट्रैक्ट्स ने समस्या को छिपा दिया, और अतिरिक्त फ़ाइलों ने ऐसा मेंटेनेंस बढ़ा दिया जिसका कोई लाभ नहीं मिला।

REST सेटअप कैसा दिखता था

  • OpenAPI spec – एक स्टैटिक फ़ाइल जो एंडपॉइंट्स का वर्णन करती थी लेकिन कभी भी 'सोर्स ऑफ ट्रुथ' (source of truth) के रूप में काम नहीं करती थी।
  • Client SDK generation step – एक CI जॉब जो JavaScript रैपर तैयार करती थी।
  • Postman collection – एक साझा टेस्टिंग आर्टिफैक्ट जिसका कोई उपयोग नहीं करता था।
  • Manual TypeScript interfaces – हाथ से लिखे गए टाइप्स जिन्हें सर्वर के साथ सिंक में रहना पड़ता था।

हर API बदलाव में इनमें से कम से कम तीन आर्टिफैक्ट्स, साथ ही वैलिडेटर और किसी भी डाउनस्ट्रीम fetch कॉल को बदलना पड़ता था। यह प्रक्रिया त्रुटिपूर्ण और धीमी थी।

tRPC ने कोडबेस को कैसे कम किया

tRPC अलग कॉन्ट्रैक्ट फ़ाइल की आवश्यकता को समाप्त कर देता है। सर्वर एक राउटर टाइप एक्सपोर्ट करता है; क्लाइंट उसी टाइप को इम्पोर्ट करता है। यदि बैकएंड फ़ील्ड का नाम बदल दिया जाए, तो एडिटर तुरंत मिसमैच को फ्लैग कर देता है—इसके लिए कोड चलाने या रिक्वेस्ट फेल होने की ज़रूरत नहीं पड़ती। डेवलपर ने इन्हें हटा दिया:

  • OpenAPI spec फ़ाइल।
  • Client SDK generation step।
  • अप्रयुक्त Postman collection।
  • Manual TypeScript interfaces का फोल्डर।

रिपॉजिटरी अधिक सुव्यवस्थित (leaner) हो गई, और फीडबैक डिप्लॉयमेंट के बजाय डेवलपमेंट के दौरान ही मिलने लगा।

tRPC की सीमाएं

tRPC तभी काम करता है जब दोनों छोर (ends) TypeScript का उपयोग करते हों। यह तब कमज़ोर पड़ता है यदि:

  • मोबाइल टीम Swift या Kotlin का उपयोग करती है।
  • API का उपयोग बाहरी पार्टनर्स द्वारा किया जाना हो।
  • आपको एक पब्लिक, लैंग्वेज-एग्नोस्टिक (language-agnostic) इंटरफ़ेस की आवश्यकता हो।

माइग्रेशन के लिए वास्तव में क्या आवश्यक था

दो सप्ताह का यह प्रयास केवल कॉपी-एंड-पेस्ट से कहीं अधिक था। डेवलपर को निम्नलिखित कार्य करने पड़े:

  • tRPC के क्लाइंट फंक्शन्स का उपयोग करने के लिए हर fetch कॉल को फिर से लिखना।
  • एरर-हैंडलिंग लॉजिक को एडजस्ट करना।
  • उन UI कंपोनेंट्स को अपडेट करना जो रॉ HTTP रिस्पॉन्स से जुड़े लोडिंग और रिट्राय स्टेट्स (loading and retry states) पर निर्भर थे।

आगे बढ़ने से पहले पूछने योग्य प्रश्न

  • क्या फ्रंटएंड और बैकएंड दोनों TypeScript का उपयोग करते हैं? एक साझा टाइप सिस्टम के बिना, tRPC अपना मुख्य लाभ खो देता है।
  • क्या दोनों पक्षों के लिए एक ही टीम जिम्मेदार है? ओनरशिप गैप्स (ownership gaps) से कॉन्ट्रैक्ट ड्रिफ्ट (contract drift) की समस्या फिर से आ सकती है।
  • क्या आप किसी ठोस बग को ठीक कर रहे हैं या किसी ट्रेंड का पीछा कर रहे हैं? उत्पादकता में वृद्धि वास्तविक है, लेकिन इसे किसी मौजूदा समस्या (pain point) का समाधान करना चाहिए।

2025 के लिए एक हाइब्रिड दृष्टिकोण

कई टीमें दोनों स्टैक चलाकर एक सही संतुलन (sweet spot) बना लेती हैं:

  • इंटरनल एप्लिकेशन लेयर्स के लिए tRPC, जहाँ कोडबेस पूरी तरह से TypeScript है और एक ही टीम सर्वर और क्लाइंट की मालिक है।
  • वेबहुक्स (webhooks), पब्लिक APIs और पार्टनर इंटीग्रेशन के लिए REST, जहाँ लैंग्वेज-एग्नोस्टिक एक्सेस की आवश्यकता होती है।

प्रत्येक सतह (surface) के लिए सही टूल का उपयोग करने से इंटरनल डेवलपमेंट तेज़ रहता है और बाहरी उपभोक्ताओं के लिए आवश्यक खुलापन भी बना रहता है।

निष्कर्ष (Takeaway): REST को tRPC से बदलने से डुप्लिकेट कॉन्ट्रैक्ट आर्टिफैक्ट्स को समाप्त किया जा सकता है और एडिटिंग के समय ही बग्स का पता लगाया जा सकता है, लेकिन लाभ तभी मिलते हैं जब पूरा स्टैक TypeScript साझा करता है और टीम माइग्रेशन की लागत को वहन कर सकती है। एक मिश्रित रणनीति आपको गैर-TypeScript उपभोक्ताओं को बाहर रखे बिना लाभ उठाने की अनुमति देती है।