एका फ्रंटएंड टीमने केवळ डेव्हलपमेंटसाठी वापरली जाणारी एक type-safe API-mocking layer कार्यान्वित केली आहे. Axios interceptors आणि Vite च्या tree-shaking चा वापर केल्यामुळे, प्रोडक्शन बंडलवर कोणताही परिणाम होत नाही. बॅकएंड एंडपॉइंट्सची प्रतीक्षा करत असताना इंजिनिअर्स त्यांच्या नेहमीच्या पद्धतींनी डेटा फेच (fetch) करू शकतात आणि नंतर रिअल API वापरण्यासाठी फक्त एक 'environment flag' बदलणे पुरेसे असते.

टीमला मॉक करण्यासाठी चांगल्या पद्धतीची गरज का भासली

जेव्हा बॅकएंड रूट अपूर्ण असते, तेव्हा फ्रंटएंड डेव्हलपर्सना अडथळा येतो. एखादा घटक (component) मध्येच रिस्पॉन्स हार्ड-कोड करणे किंवा संपूर्ण UI मध्ये if (process.env.NODE_ENV === 'development') सारखे ब्लॉक्स वापरणे हा तात्पुरता उपाय असला तरी, यामुळे 'technical debt' निर्माण होतो. हे मॉक ऑब्जेक्ट्स नंतर कंपोनंटच्या लॉजिकचा भाग बनतात, ज्यामुळे प्रोडक्शनमध्ये चुकीचा डेटा जाण्याचा धोका वाढतो आणि कोड वाचणे व टेस्ट करणे कठीण होते.

टीमला प्रत्येक मॉक कंपोनंट ट्रीच्या बाहेर नेणे, फ्रंट आणि बॅकएंडमध्ये एक करार (contract) लागू करणे आणि प्रोडक्शन बिल्डमध्ये कोणतीही अतिरिक्त गोष्ट जाणार नाही याची खात्री करणे आवश्यक होते.

टीमने अवलंबलेली तीन-टप्प्यांची प्रक्रिया

  1. Contract meeting – फ्रंटएंड आणि बॅकएंड इंजिनिअर्स एकत्र बसून प्रत्येक रिक्वेस्ट, तिचा URL, मेथड आणि अपेक्षित payload यांची यादी तयार करतात.
  2. Typed contract – ते या यादीचे TypeScript interface मध्ये रूपांतर करतात, जे रिक्वेस्ट आणि रिस्पॉन्सच्या आकारासाठी (shapes) एकमेव सत्य स्रोत (single source of truth) बनते.
  3. Interceptor wiring – एक Axios interceptor प्रत्येक बाहेर जाणाऱ्या रिक्वेस्टची तपासणी करतो. जर URL नोंदणीकृत मॉकशी जुळत असेल, तर interceptor मॉक डेटा परत करतो; अन्यथा रिक्वेस्ट थेट लाइव्ह सर्व्हरकडे जाते.

कारण interceptor हीच एकमेव जागा आहे जिथे मॉक लॉजिक असते, त्यामुळे कंपोनंट कोडमध्ये कोणताही बदल करावा लागत नाही. डेव्हलपर्स कोणताही कंडिशनल लॉजिक न वापरता useQuery सारखे त्यांचे नेहमीचे डेटा-फेचिंग हुक्स वापरू शकतात.

प्रोडक्शनमधील अनावश्यक वाढ (bloat) कशी टाळली जाते

टीमने तीन सुरक्षा उपाय (safeguards) वापरले आहेत, ज्यामुळे Rollup (Vite द्वारे वापरले जाणारे bundler) प्रोडक्शनसाठी बिल्ड करताना मॉक कोड पूर्णपणे काढून टाकू शकते:

  • import.meta.env.DEV प्रोडक्शन बिल्डमध्ये false म्हणून रिझॉल्व्ह होते, त्यामुळे tree-shaking दरम्यान संपूर्ण interceptor मॉड्यूल निघून जाते.
  • युनिट टेस्ट्स चालवताना MODE व्हेरिएबल test व्यतिरिक्त इतर काहीतरी सेट केले जाते, ज्यामुळे फक्त टेस्टसाठी लागणारा कोड वेगळा राहतो.
  • एक कस्टम फ्लॅग, VITE_ENABLE_MSW, बाय डीफॉल्ट false असतो आणि मॉक सक्रिय करण्यासाठी तो स्पष्टपणे चालू करावा लागतो.

जेव्हा या तिन्ही अटी 'false' असतात, तेव्हा मॉक रजिस्ट्री अंतिम बंडलमध्ये कधीच जात नाही.

मॉक फाइल्सचे आयोजन

रिपॉझिटरी (repo) फीचर-केंद्रित लेआउटचे पालन करते:

  • interfaces/ – कॉन्ट्रॅक्ट मीटिंगमधून तयार केलेल्या TypeScript डेफिनिशन्स येथे असतात.
  • scenarios.ts – प्रत्येक एंडपॉइंटसाठी यशस्वी रिस्पॉन्स आणि एरर केसेसची प्रत्यक्ष उदाहरणे यात असतात.
  • devHandlers.ts – हे एक मध्यवर्ती रजिस्ट्री म्हणून काम करते जे URL ला सिनारियो डेटाशी मॅप करते आणि Axios मध्ये interceptor जोडते.

एक लहान स्कॅफोल्डिंग स्क्रिप्ट (scaffolding script) या फाइल्स आपोआप तयार करू शकते: तिला URL आणि मॅचिंग इंटरफेस द्या, आणि ती स्टब फाइल्स तयार करून मॉक रजिस्टर करते. ही स्क्रिप्ट प्रोडक्शन कोड पाथच्या बाहेर असते, त्यामुळे त्याचा बंडल साइजवर कोणताही परिणाम होत नाही.

टीमला काय मिळाले

  • कंपोनंट्समध्ये शून्य मॉक्स – सर्व बनावट डेटा एका समर्पित लेयरमध्ये असतो, ज्यामुळे UI कोड स्वच्छ राहतो.
  • End-to-end type safety – मॉक डेटा रिअल रिस्पॉन्ससाठी वापरल्या जाणाऱ्या TypeScript interfaces नुसारच असतो, त्यामुळे विसंगती (mismatches) कंपाईल टाइमलाच पकडल्या जातात.
  • प्रोडक्शनमध्ये कोणताही भार नाही – Tree-shaking मुळे interceptor आणि मॉक डेटा पूर्णपणे निघून जातो, ज्यामुळे बंडल साइज बदलत नाही.
  • डेव्हलपमेंट आणि टेस्टसाठी सामायिक सिनारिओ – एकच मॉक डेफिनिशन्स स्थानिक डेव्हलपमेंट आणि ऑटोमेटेड टेस्ट दोन्हीसाठी वापरली जाते, ज्यामुळे कामाची पुनरावृत्ती कमी होते.

तडजोड आणि मर्यादा

हा दृष्टिकोन खऱ्या बॅकएंडची जागा घेत नाही. जर मॉक कॉन्ट्रॅक्ट लाइव्ह API पेक्षा वेगळे झाले, तर डेव्हलपर्सना ते तेव्हाच समजते जेव्हा ते 'environment flag' बदलतात.

पुढे काय पाहावे

  • Tooling integration
  • Broader adoption
  • Performance monitoring

निष्कर्ष स्पष्ट आहे: मॉक लॉजिकला 'typed, environment-gated layer' मध्ये हलवल्यामुळे फ्रंटएंड टीम्सना कंपोनंट्स शुद्ध ठेवता येतात, 'type-safe' राहता येते आणि लपवलेले मॉक पेलोड्स न ठेवता प्रोडक्शन बिल्ड्स पाठवता येतात. एक सामायिक करार (shared contract) राखणे ही अधिक सुलभ डेव्हलपमेंट वर्कफ्लो आणि स्वच्छ कोडबेस मिळवण्यासाठीची किंमत आहे.