जब आप एपीआई को लपेटने के लिए रूबी का उपयोग करते हैं, तो आपके पास इसे कॉन्फ़िगर करने का एक तरीका होना चाहिए। हो सकता है कि रैपर को उपयोगकर्ता नाम और गुप्त कुंजी, या शायद केवल एक होस्ट की आवश्यकता हो।
इसे संभालने के कुछ अलग तरीके हैं। तो आपको किसे चुनना चाहिए?
आसान, वैश्विक तरीका
आप चाहते हैं कि आपकी सेवा हमेशा की तरह कार्य करे। इससे कोई फर्क नहीं पड़ता कि आप अपने ऐप में कहीं भी हैं, आप इसे उपयोग के लिए तैयार रखेंगे। अन्यथा, आप इसका उपयोग करने की प्रत्येक पंक्ति के लिए इसे कॉन्फ़िगर करने की तीन पंक्तियाँ खर्च करेंगे!
आप स्थिरांक या वर्ग विशेषताओं का उपयोग करके कॉन्फ़िगरेशन को वैश्विक बना सकते हैं:
ProductApi.root = "https://staging-host.example.com/"
ProductApi.user = "justin"
ProductApi.secret = "mysecret123"
def show
@product = ProductApi.find(params[:id])
end
बहुत सारे रत्न इस पैटर्न का उपयोग करते हैं। यह लिखना बहुत आसान है, और वास्तव में उपयोग करना आसान है। लेकिन इसमें कुछ बड़ी समस्याएं हैं:
-
आपके पास केवल एक
ProductApi
हो सकता है .यदि आप उत्पाद API को दो अलग-अलग उपयोगकर्ताओं के रूप में उपयोग करना चाहते हैं, या एक ही ऐप से अलग-अलग सर्वरों को हिट करना चाहते हैं, तो आप भाग्य से बाहर हैं।
-
ProductApi
वैश्विक डेटा है जिसे गलती से बदलना आसान है।अगर कोई थ्रेड या आपके ऐप का कोई हिस्सा बदल गया है
ProductApi.user
, बाकी सब कुछProductApi
. का उपयोग कर रहा है टूट जाएगा। और वे दर्दनाक हैं ट्रैक करने के लिए बग।
तो, वर्ग चर में कुछ समस्याएं हैं। क्या होगा यदि आपने इंस्टेंसको कॉन्फ़िगर किया है इसके बजाय आपके उत्पाद API वर्ग का?
#initialize
के साथ यह कैसा दिखेगा ?
अगर आपने इंस्टेंस का इस्तेमाल किया है, तो आपको ज़रूरत पड़ने पर अपना एपीआई रैपर बनाना और कॉन्फ़िगर करना होगा:
def show
product_api = ProductApi.new(
root: "https://staging-host.example.com/",
user: "justin",
secret: "mysecret123")
@product = product_api.find(params[:id])
end
अब, जब भी आप इसका उपयोग करते हैं, आप अपने एपीआई को अलग-अलग विवरण पास कर सकते हैं। कोई अन्य विधि या थ्रेड आपके इंस्टेंस का उपयोग नहीं कर रहे हैं, इसलिए आपको इसे जाने बिना इसे बदलने के बारे में चिंता करने की ज़रूरत नहीं है।
यह बेहतर लगता है। लेकिन यह अभी भी उतना आसान नहीं है जितना होना चाहिए। चूंकि आपको अपना API हर बारकॉन्फ़िगर करना होता है आप इसका इस्तेमाल करते हैं।
अधिकांश समय आप परवाह नहीं करते कि एपीआई कैसे स्थापित किया जाता है, आप इसे केवल समझदार विकल्पों के साथ उपयोग करना चाहते हैं। लेकिन जब आप इंस्टेंस के साथ काम कर रहे हों, तो आपके ऐप के हर हिस्से जो एपीआई का उपयोग करता है, उसे यह जानना होगा कि इसे कैसे कॉन्फ़िगर किया जाए।
लेकिन वैश्विक पहुंच की सुविधा प्राप्त करने का एक तरीका है, अच्छे डिफ़ॉल्ट का उपयोग करना, जबकि आप अभी भी जरूरत पड़ने पर इसे बदलने में सक्षम हैं।
और यह पैटर्न हर समय एक दिलचस्प जगह पर दिखाई देता है:OS X और iOS विकास।
आप अच्छे डिफ़ॉल्ट कैसे प्राप्त करते हैं और लचीलापन?
क्या होगा यदि आप अपने एपीआई रैपर के प्रत्येक इंस्टेंस को कॉन्फ़िगर कर सकते हैं, लेकिन आपके पास वैश्विक "डिफ़ॉल्ट" इंस्टेंस भी था जब आपको परवाह नहीं थी?
आपको यह "डिफ़ॉल्ट कुछ" या "साझा जो भी" पैटर्न पूरे आईओएस और मैक ओएस एसडीके में दिखाई देगा:
[[NSURLSession sharedSession] downloadTaskWithURL:@"https://www.google.com"];
[[NSFileManager defaultManager] removeItemAtPath:...];
और आप अभी भी इन वर्गों के उदाहरणों के लिए पूछ सकते हैं यदि आपको डिफ़ॉल्ट की तुलना में अधिक की आवश्यकता है:
NSURLSession *session = [NSURLSession sessionWithConfiguration:...];
NSFileManager fileManager = [[NSFileManager alloc] init];
आप रूबी में default_api
. के साथ ऐसा कुछ बना सकते हैं कक्षा विधि:
def show
@product = ProductApi.default_product_api.find(params[:id])
end
...
def show_special
special_product_api = ProductApi.new(
root: "https://special-product-host.example.com/"
user: "justin"
secret: "mysecret123")
@special_product = special_product_api.find(params[:id])
end
और कार्यान्वयन कुछ इस तरह दिख सकता है:
class ProductApi
def initialize(root:, user:, secret:)
@root, @user, @secret = root, user, secret
end
def self.default_api
@default_api ||= new(
root: ENV['PRODUCT_API_ROOT'],
user: ENV['PRODUCT_API_USER'],
secret: ENV['PRODUCT_API_SECRET'])
end
def find(product_id)
...
end
end
यहां, मैंने default_api
. में पर्यावरण चर का उपयोग किया है , लेकिन आप कॉन्फ़िगरेशन फ़ाइलों का भी उपयोग कर सकते हैं। और आप स्विच कर सकते हैं ||=
इसके बजाय थ्रेड- या अनुरोध-स्थानीय संग्रहण का उपयोग करने के लिए।
लेकिन यह एक अच्छी शुरुआत है।
मैंने देखा है कि अधिकांश रत्न, जैसे ट्विटर रत्न, आपको आवश्यकता होने पर प्रत्येक एपीआई ऑब्जेक्ट को कॉन्फ़िगर और बना देगा। यह एक ठीक समाधान है (हालाँकि मैं आमतौर पर लोगों को इन्हें ग्लोबल्स को असाइन करते हुए देखता हूँ वैसे भी )।
लेकिन अगर आप एक कदम और आगे बढ़ते हैं, और पूर्व-कॉन्फ़िगर किए गए डिफ़ॉल्ट ऑब्जेक्ट का भी उपयोग करते हैं, तो आपके पास अधिक आरामदायक समय होगा।