सर्वर और क्लाइंट के बीच इंटरफ़ेस साझा करना इतना बुरा विचार क्यों है?


12

जब मैं एक HTTP सर्वर और उसके क्लाइंट के बीच इंटरफ़ेस साझा करने के तरीके के बारे में पता चला तो मैं स्प्रिंग क्लाउड नेटफ्लिक्स प्रलेखन पढ़ रहा था । वे इस उदाहरण का उपयोग माइक्रोसिस्टर्स के लिए करते हैं, हालांकि इसका कोई कारण नहीं है कि यह जेनेरिक HTTP संचार का विस्तार नहीं कर सकता है:

// The shared interface, in a common library
public interface UserService {
    @RequestMapping(method = GET, value = "/users/{id}")
    User getUser(@PathVariable long id);
}

// The controller, on the server
@RestController
public class UserResource implements UserService {
}

// The same interface used for the client
@FeignClient("users")
public interface UserClient extends UserService {
}

यह एक इंटरफ़ेस को परिभाषित करता है जो सर्वर के रूप में उपयोग किया जाता है (स्प्रिंग @RestControllerइसे एक HTTP सर्वर में बदल देता है) और एक क्लाइंट (Feign @FeignClientइसे HTTP क्लाइंट उपयोग के लिए सेट करता है)। सर्वर और क्लाइंट क्लास कार्यान्वयन का उपयोग अलग-अलग परियोजनाओं में किया जा सकता है लेकिन फिर भी यह सुनिश्चित करने के लिए एक ही इंटरफ़ेस का उपयोग करते हैं कि प्रकार मेल खाते हैं।

हालांकि, उदाहरण के नीचे वे निम्नलिखित चेतावनी देते हैं:

नोट: आमतौर पर सर्वर और क्लाइंट के बीच इंटरफेस साझा करना उचित नहीं है। यह तंग युग्मन का परिचय देता है, और वास्तव में स्प्रिंग एमवीसी के साथ अपने वर्तमान रूप में काम नहीं करता है (विधि पैरामीटर मैपिंग विरासत में नहीं मिली है)।

ठीक है, इसलिए अभी यह अच्छी तरह से एकीकृत नहीं है ... लेकिन यह हिस्सा कोड को साझा करने और सर्वर और क्लाइंट के बीच युग्मन शुरू करने के खिलाफ चेतावनी के बाद आता है , जो उन्हें लगता है कि अधिक महत्वपूर्ण है। वे ऐसा क्यों सोचते हैं कि इस तरह से इंटरफ़ेस साझा करना इतना बुरा विचार है?

इसके बिना, आप यह गारंटी देने की क्षमता खो देते हैं कि सर्वर और क्लाइंट एक दूसरे को डेटा भेजते हैं जिसे वे दोनों समझ सकते हैं। आप एक क्षेत्र को जोड़ सकते हैं लेकिन दूसरे को नहीं और केवल रनटाइम तक बेमेल को खोज सकते हैं। मेरे दिमाग में, यह युग्मन शुरू नहीं कर रहा है , लेकिन केवल पहले से मौजूद युग्मन का खुलासा कर रहा है। क्या सर्वर को पूरी तरह से स्वतंत्र बनाने की आवश्यकता है ताकि वे यह जान सकें कि उन्हें किस प्रकार का डेटा प्राप्त होगा?


1
युग्मन जो मौजूद है, क्लाइंट / सर्वर द्वारा संधारित डेटा / स्वरूपण के संदर्भ में, प्रोटोकॉल द्वारा निर्धारित किया जाता है - एक दस्तावेज का एक टुकड़ा जिसे एक सम्मेलन के रूप में इस्तेमाल किया जा सकता है । इंटरफ़ेस साझा करके शुरू की गई युग्मन एक संकलन-समय युग्मन है - विचार करें कि क्या होता है जब इंटरफ़ेस बदल जाता है (उदाहरण के लिए एक पिछड़े-असंगत तरीके से), लेकिन उस इंटरफ़ेस का उपयोग करने वाले क्लाइंट / सर्वर कोड को अलग-अलग समय पर तैनात किया जाता है। उस तैनाती-समय युग्मन को प्रबंधित करना कठिन हो सकता है, खासकर नेटफ्लिक्स के पैमाने पर।
Castaglia

1
मुझे पूरा यकीन है कि मैं नेटफ्लिक्स के पैमाने पर काम नहीं कर रहा हूं :) लेकिन अगर इंटरफेस को पिछड़े- असंगत तरीके से बदल दिया जाता है, तो क्या यह त्रुटि को संकलित समय पर पाए जाने के बजाय रनटाइम पर पाए जाने से नहीं बदलता है? जब वे धीरे-धीरे सभी सर्वरों को अपग्रेड करते हैं, तो क्या वे कुछ फ़ंक्शन कॉल को विफल होने के लिए ठीक मानते हैं?
बेन एस

1
संभवत:; ग्राहक कोड पर निर्भर करता है। अन्य मामले पर भी विचार करें: सर्वर पहले अपग्रेड किए जाते हैं, और क्लाइंट्स को अब (अनपेक्षित रूप से)
फेल

1
बस जिज्ञासु, इस इंटरफ़ेस को साझा करके, क्या यह सीमित करता है कि आप ग्राहकों को किन भाषाओं / स्टैक से बना सकते हैं?
जेएफओ

हां - यह एक जावा फ़ाइल है इसलिए आपको जावा का उपयोग करना होगा। आप एक और JVM भाषा का उपयोग करने में सक्षम हो सकते हैं लेकिन मैंने इसकी कोशिश नहीं की है।
बेन एस

जवाबों:


6

टिप्पणियों में कहा गया कारण यह है कि यह आपके क्लाइंट प्लेटफ़ॉर्म को आपके सर्वर प्लेटफ़ॉर्म पर कसकर युग्मित करने का परिणाम है। यहां, इसका मतलब है कि आपके क्लाइंट को आपके सर्वर के अपेक्षित अनुबंध को समझने के लिए सर्वर पर जिस भाषा / मंच का उपयोग किया जा रहा है, उसका उपयोग करना आवश्यक है। ध्यान दें कि समान कोड (किसी विशिष्ट भाषा / मंच की एक कलाकृति) को साझा करने और किसी विशिष्ट अनुबंध पर सहमति देने के बीच अंतर है।

इसके बजाय कई परियोजनाएं अपने अनुबंधों के लिए प्रलेखन का उपयोग करती हैं। मानक प्रोटोकॉल (उदा। REST) ​​पर उदासीन प्रारूप (जैसे JSON) में उदाहरण अनुरोध और प्रतिक्रियाएँ। ( उदाहरण के लिए, स्ट्राइप एपीआई डॉक्स देखें )। क्योंकि हर संभव क्लाइंट प्लेटफ़ॉर्म के लिए कोड-आधारित अनुबंध लिखना अव्यावहारिक है जिसका आप उपयोग या अनुमति देना चाहते हैं। अभी भी अन्य लोग तटस्थ अनुबंधों को परिभाषित करने के लिए एपीआई प्रबंधन उपकरणों का उपयोग करते हैं ।

फ़ील्ड जोड़ने का आपका उदाहरण एक अलग चिंता का विषय है - एपीआई कॉन्ट्रैक्ट्स को संस्करणित करना क्यों महत्वपूर्ण है, इसका एक उदाहरण। ग्राहकों को उस संस्करण का उपयोग करने दें जिसके लिए वे डिज़ाइन किए गए हैं। पुराने के साथ एक पिछड़ा-असंगत नया एपीआई संस्करण मौजूद है। पुराने संस्करण के लिए क्लाइंट तब तक काम करना जारी रखता है जब तक कि उसकी टीम इसे अपडेट करने के लिए या जब तक आप पुराने संस्करण को नहीं हटाते हैं (एक डिप्रेसेशन / माइग्रेशन अवधि के बाद)। समानांतर परिवर्तन देखें ।

चेतावनी (अंतर्निहित सलाह) के बाद चेतावनी क्लाइंट और सर्वर को उन तरीकों और पेस में विकसित होने में मदद करती है जो प्रत्येक के लिए समझ में आता है। यदि आप यथोचित गारंटी दे सकते हैं कि आपका सर्वर और क्लाइंट हमेशा एक ही भाषा / मंच साझा करेंगे और एक ही गति से विकसित होंगे, तो आपके अनुबंध के रूप में भाषा और मंच-विशिष्ट कोड विरूपण साक्ष्य का उपयोग करना संभवतः ठीक होगा। हालांकि, यह शायद एक उचित उम्मीद नहीं है, खासकर नेटफ्लिक्स ओएसएस को लक्षित करने वाली परियोजनाओं के लिए (कुछ विशेष रूप से क्लाउड स्केलेबिलिटी और प्रदर्शन के लिए तैयार की गई, उस सभी आवश्यक जटिलता के साथ)।


2
क्या क्लाइंट को वास्तव में इंटरफ़ेस का उपयोग करने की उम्मीद है? मैंने हमेशा इस तरह के निर्माणों को एक क्लाइंट को आसान बनाने के तरीके के रूप में देखा है। आखिर आप अभी भी एक अलग भाषा में एक अन्य क्लाइंट लिख सकते हैं।
जिमी टी।

1
वास्तव में, एपीआई अभी भी मौजूद रहेगा, इसके रूट परिभाषाओं के साथ, कुछ भी क्लाइंट को किसी अन्य भाषा में बनाने से रोकता है, लेकिन जब तक आप जावा का उपयोग करते हैं, इंटरफ़ेस का उपयोग कर सकते हैं
लियोनार्डो विलेला
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.