एका डेव्हलपरने अंतर्गत टूलमध्ये REST API ऐवजी tRPC वापरण्यासाठी दोन आठवडे खर्च केले.
हा बदल का महत्त्वाचा होता
जुन्या स्टॅकमुळे आम्हाला DTO, एक validator आणि frontend साठी TypeScript प्रकारांचा (types) एक वेगळा संच मेंटेन करावा लागत असे. बॅकएंडमधील एखादे फील्ड (field) नाव बदलले, तरी API अजूनही 200 रिटर्न करत असे, UI रेंडर होत राहत असे आणि ही त्रुटी (bug) फक्त “undefined” व्हॅल्यूजच्या स्वरूपात दिसून येत असे. टीममधील कोणाही व्यक्तीच्या लक्षात येण्यापूर्वीच एका ग्राहकाने ही समस्या पकडली. REST कॉन्ट्रॅक्ट्समुळे ही समस्या लपली होती आणि अतिरिक्त फाईल्समुळे मेंटेनन्सचा असा भार वाढला होता ज्याचा कोणताही फायदा झाला नाही.
REST सेटअप कसा होता
- OpenAPI spec – एक स्टॅटिक फाईल जी एंडपॉइंट्सचे वर्णन करत असे, परंतु ती कधीही 'source of truth' म्हणून काम करत नसे.
- Client SDK generation step – एक CI जॉब जो JavaScript wrapper तयार करत असे.
- Postman collection – एक शेअर केलेली टेस्टिंग आर्टिफॅक्ट (artifact) ज्याचा कोणीही वापर करत नसे.
- Manual TypeScript interfaces – हाताने लिहिलेले types जे सर्व्हरसोबत सिंक (sync) ठेवावे लागत असत.
प्रत्येक API बदलामुळे यातील किमान तीन आर्टिफॅक्ट्सना, शिवाय validator आणि कोणत्याही डाउनस्ट्रीम fetch कॉल्सना स्पर्श करावा लागत असे. ही प्रक्रिया त्रुटीपूर्ण (error-prone) आणि संथ होती.
tRPC ने कोडबेस कसा कमी केला
tRPC वेगळी कॉन्ट्रॅक्ट फाईल काढून टाकते. सर्व्हर एक router type एक्सपोर्ट करतो; क्लायंट तोच 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कॉल पुन्हा लिहावा लागला. - एरर-हँडलिंग लॉजिकमध्ये बदल करावा लागला.
- रॉ HTTP रिस्पॉन्सवर आधारित लोडिंग आणि retry स्टेट्सवर अवलंबून असलेल्या UI कंपोनंट्सना अपडेट करावे लागले.
पुढे जाण्यापूर्वी विचारायचे प्रश्न
- Frontend आणि backend दोन्ही TypeScript वापरतात का? शेअर केलेल्या टाईप सिस्टमशिवाय, tRPC त्याचा मुख्य फायदा गमावते.
- दोन्ही बाजूंची जबाबदारी एकाच टीमची आहे का? ओनरशिपमधील त्रुटींमुळे पुन्हा कॉन्ट्रॅक्ट ड्रिफ्ट (contract drift) होऊ शकतो.
- तुम्ही एखादी ठोस त्रुटी (bug) सुधारत आहात की केवळ ट्रेंडच्या मागे जात आहात? उत्पादकता वाढणे (productivity boost) वास्तविक आहे, परंतु त्याने अस्तित्वात असलेली समस्या सोडवणे आवश्यक आहे.
2025 साठी हायब्रिड दृष्टिकोन
अनेक टीम्स दोन्ही स्टॅक्स चालवून एक योग्य मध्यम मार्ग (sweet spot) शोधतात:
- अंतर्गत ॲप्लिकेशन लेयर्ससाठी tRPC, जिथे संपूर्ण कोडबेस TypeScript आहे आणि सर्व्हर आणि क्लायंटची मालकी एकाच टीमकडे आहे.
- वेबहुक्स (webhooks), पब्लिक APIs आणि पार्टनर इंटिग्रेशनसाठी REST, जिथे लँग्वेज-अग्नोस्टिक ॲक्सेसची आवश्यकता असते.
प्रत्येक कामासाठी योग्य साधन वापरल्यामुळे अंतर्गत डेव्हलपमेंट वेगवान राहते आणि बाह्य ग्राहकांसाठी आवश्यक असलेली सुलभता (openness) देखील टिकून राहते.
थोडक्यात सांगायचे तर (Takeaway): REST च्या जागी tRPC वापरल्यामुळे डुप्लिकेट कॉन्ट्रॅक्ट आर्टिफॅक्ट्स दूर होऊ शकतात आणि एडिटिंग दरम्यानच त्रुटी (bugs) समोर येऊ शकतात, परंतु याचा फायदा तेव्हाच होतो जेव्हा संपूर्ण स्टॅक TypeScript शेअर करतो आणि टीम मायग्रेशनचा खर्च पेलू शकते. मिश्र धोरणामुळे (mixed strategy) तुम्ही नॉन-TypeScript ग्राहकांना वगळल्याशिवाय याचे फायदे मिळवू शकता.
