• सॉफ्टवेयर इंजीनियरिंग में API एक मुख्य टूल है, और अच्छे API की वांछनीय विशेषता यह है कि वह इतना परिचित और सरल हो कि लगभग उबाऊ लगे
  • API एक बार सार्वजनिक हो जाए तो उसे बदलना मुश्किल होता है, इसलिए यूज़र environment को न तोड़ने का सिद्धांत (WE DO NOT BREAK USERSPACE) महत्वपूर्ण है
  • यदि बदलाव अपरिहार्य हो, तो versioning की ज़रूरत पड़ती है, लेकिन यह जटिलता और maintenance cost को बहुत बढ़ाने वाली एक ज़रूरी बुराई है
  • API की गुणवत्ता अंततः प्रोडक्ट के अपने मूल्य पर निर्भर करती है, और खराब ढंग से डिज़ाइन किए गए प्रोडक्ट के लिए अच्छा API बनाना कठिन होता है
  • स्थिरता और विस्तारयोग्यता के लिए API key आधारित authentication, idempotency, rate limit, cursor-based pagination आदि पर विचार करना चाहिए

प्रस्तावना: API डिज़ाइन का महत्व और संदर्भ

  • आधुनिक सॉफ्टवेयर इंजीनियर के प्रमुख कामों में से एक API के साथ इंटरैक्ट करना है
  • लेखक के पास भी REST, GraphQL, command-line tools आदि जैसे विभिन्न रूपों में public और internal API को डिज़ाइन/इम्प्लीमेंट/उपयोग करने का अनुभव है
  • मौजूदा API डिज़ाइन सलाह अक्सर जटिल अवधारणाओं (REST की परिभाषा, HATEOAS आदि) पर अत्यधिक केंद्रित रहती है
  • यह लेख वास्तविक अनुभव के आधार पर व्यावहारिक API डिज़ाइन सिद्धांतों को व्यवस्थित करता है

परिचितपन और लचीलापन का संतुलन: अच्छे API की पहली शर्त

  • अच्छा API एक 'साधारण और उबाऊ' API होता है, यानी उसका इस्तेमाल पहले देखे गए API जैसा महसूस होना चाहिए
  • यूज़र API से ज़्यादा अपने लक्ष्य को पूरा करने पर ध्यान देता है, इसलिए low barrier वाली डिज़ाइन ज़रूरी है
  • एक बार public हो जाने के बाद API को बदलना बहुत मुश्किल हो जाता है, इसलिए शुरुआती डिज़ाइन चरण में सावधानी चाहिए
  • डेवलपर जहाँ संभव हो API को सरल रखना चाहते हैं, वहीं लंबी अवधि की flexibility बचाए रखने की चिंता भी बनी रहती है
  • नतीजतन, परिचितपन और दीर्घकालिक flexibility के बीच संतुलन ही मुख्य चुनौती है

यूज़रस्पेस को कभी न तोड़ें (WE DO NOT BREAK USERSPACE)

  • मौजूदा response structure में fields जोड़ना ज़्यादातर मामलों में समस्या नहीं बनता
  • लेकिन field हटाना, type या structure बदलना सभी consumer code को तोड़ सकता है
  • API maintainers की यह ज़िम्मेदारी है कि वे मौजूदा यूज़र्स के software को जानबूझकर न तोड़ें
  • HTTP के referer header की वर्तनी गलती तक न सुधारे जाने की वजह भी यूज़रस्पेस को बचाए रखने की संस्कृति है

API को तोड़े बिना बदलना: versioning रणनीति

  • केवल अनिवार्य होने पर ही API में breaking changes की अनुमति देनी चाहिए, और ऐसे में versioning ही सही रास्ता है
  • पुराने और नए version को एक साथ चलाते हुए gradual migration के लिए प्रेरित करना चाहिए
  • version identifier को URL(/v1/), header आदि कई तरीकों से इस्तेमाल किया जा सकता है, और यूज़र अपनी गति से migrate कर सकते हैं
  • versioning के साथ बहुत बड़ा maintenance cost (endpoint बढ़ना, testing, support) और यूज़र confusion जैसी कमियाँ आती हैं
  • Stripe की तरह अंदरूनी translation layer रखी जाए तब भी मूल जटिलता से बचा नहीं जा सकता
  • API versioning अपनाना आख़िरी उपाय होना चाहिए

API की सफलता पूरी तरह प्रोडक्ट के मूल्य पर निर्भर करती है

  • API मूलतः वास्तविक business product का सिर्फ interface है
  • OpenAI, Twilio जैसी API में भी आखिरकार यूज़र को चाहिए वह functionality जो API उपलब्ध कराती है
  • यदि प्रोडक्ट मूल्यवान है, तो API असुविधाजनक होने पर भी लोग उसका उपयोग करेंगे
  • API quality एक तरह की margin विशेषता है: यह तब चयन का कारक बनती है जब मूल प्रतिस्पर्धात्मक क्षमता लगभग समान हो
  • इसके विपरीत, बिल्कुल API न होना तकनीकी यूज़र्स के लिए बड़ा अवरोध है

अगर प्रोडक्ट डिज़ाइन खराब है, तो API भी अच्छा नहीं बन सकता

  • तकनीकी रूप से परिष्कृत API होने पर भी यदि प्रोडक्ट की market viability नहीं है, तो उसका अर्थ सीमित रह जाता है
  • इससे भी महत्वपूर्ण बात यह है कि यदि बुनियादी resource structure अलॉजिकल या अक्षम है, तो वह API में भी दिखेगा
  • उदाहरण के लिए, comments को linked list में स्टोर करने वाली system में RESTful डिज़ाइन भी स्वाभाविक रूप से निकालना कठिन हो जाता है
  • UI में जो तकनीकी समस्याएँ छिप सकती हैं, वे API में खुलकर सामने आ जाती हैं और यूज़र पर सिस्टम की अनावश्यक समझ थोपती हैं

authentication और यूज़र्स की विविधता

  • long-lived API key आधारित authentication को अनिवार्य रूप से support करना चाहिए
  • OAuth जैसी अधिक secure विधि का अतिरिक्त support दिया जाए तब भी, API key का entry barrier बहुत कम होता है
  • API consumer सिर्फ इंजीनियर नहीं होते; कई non-developer भी होते हैं (sales, planning, students, hobby developers आदि)
  • कठिन या जटिल authentication आवश्यकताएँ (जैसे OAuth) गैर-विशेषज्ञ यूज़र्स के लिए बाधा बनती हैं

idempotency और retry handling

  • action-oriented requests (जैसे payment, state change आदि) में failure होने पर retry की सुरक्षा बहुत महत्वपूर्ण है
  • idempotency का अर्थ है यह सुनिश्चित करना कि एक ही request कई बार भेजी जाए तब भी परिणाम सिर्फ एक बार ही प्रोसेस हो
  • मानक तरीका यह है कि duplicate processing रोकने के लिए idempotency key को parameter या header के रूप में भेजा जाए
  • idempotency key को स्टोर करने के लिए Redis जैसे सरल key/value store पर्याप्त हैं, और अधिकांश मामलों में periodic expiry भी ठीक रहती है
  • read/delete requests (REST शैली) में आमतौर पर इसकी ज़रूरत नहीं होती

API सुरक्षा और rate limiting

  • कोड के जरिए API requests, यूज़र के मैनुअल ऑपरेशन की तुलना में कहीं तेज़ी से हो सकती हैं
  • अनजाने में deploy की गई एक API भी किसी अप्रत्याशित उपयोग (जैसे बड़े पैमाने के chat system) में लग सकती है
  • rate limit अनिवार्य है, और महँगे operations पर इसे और सख़्ती से लागू किया जाना चाहिए
  • किसी विशेष ग्राहक के लिए अस्थायी API disablement (killswitch) को भी एक विकल्प के रूप में सोचना चाहिए
  • response headers (X-Limit-Remaining, Retry-After आदि) के जरिए rate limit जानकारी देनी चाहिए

pagination रणनीति

  • बड़े dataset (जैसे लाखों tickets) को कुशलता से लौटाने के लिए pagination अनिवार्य है
  • offset-based pagination सरल है, लेकिन बड़े data पर धीरे-धीरे धीमी हो जाती है
  • cursor-based pagination query performance घटाए बिना बहुत बड़े dataset पर भी प्रभावी रहती है
  • cursor-based तरीका implementation और उपयोग दोनों में थोड़ा कठिन है, लेकिन लंबी अवधि में यह अनिवार्य बदलाव साबित हो सकता है
  • response में next_page field आदि शामिल करके अगले request के cursor को स्पष्ट रूप से बताना समझदारी है

optional fields और GraphQL पर दृष्टिकोण

  • महँगे या धीमे fields को default response से बाहर रखना चाहिए और ज़रूरत होने पर ही selectively जोड़ना चाहिए
  • includes parameter आदि से related data शामिल किया जा सकता है
  • GraphQL में data structure flexibility का लाभ है, लेकिन non-developer accessibility में कमी, caching/edge case की जटिलता, backend implementation की कठिनाई जैसी समस्याएँ भी हैं
  • व्यावहारिक अनुभव के आधार पर, GraphQL को सिर्फ तभी अपनाना उचित है जब इसकी वास्तव में आवश्यकता हो

internal API की विशेषताएँ

  • internal API की परिस्थितियाँ external API (public API) से कई मायनों में अलग होती हैं
  • इनके consumer अधिकांशतः पेशेवर software engineers होते हैं, इसलिए अधिक जटिल authentication या breaking changes संभव हो सकते हैं
  • फिर भी, idempotency, दुर्घटना-निवारण और operational burden को कम करने वाले डिज़ाइन सिद्धांत यहाँ भी लागू होते हैं

सारांश

  • API को बदलना कठिन और उपयोग करना आसान होना चाहिए
  • यूज़रस्पेस को न तोड़ना API maintainers का सबसे महत्वपूर्ण कर्तव्य है
  • API versioning की लागत बहुत अधिक है, इसलिए इसका उपयोग केवल आख़िरी उपाय के रूप में होना चाहिए
  • अंततः API की गुणवत्ता प्रोडक्ट के मूल मूल्य से तय होती है
  • खराब ढंग से डिज़ाइन किए गए प्रोडक्ट की सीमाएँ API स्तर पर सुधार करके भी पूरी तरह दूर नहीं की जा सकतीं
  • सरल authentication का support, ज़रूरी action requests में idempotency, और rate limiting/pagination जैसे stability उपाय महत्वपूर्ण हैं
  • internal API के लिए उपयोग और लक्षित यूज़र के अनुसार रणनीति अलग हो सकती है, लेकिन सावधानीपूर्वक डिज़ाइन की आवश्यकता बनी रहती है
  • REST, JSON जैसे format या OpenAPI आदि मूल मुद्दे नहीं हैं; स्पष्ट documentation अधिक महत्वपूर्ण है

अभी कोई टिप्पणी नहीं है.

अभी कोई टिप्पणी नहीं है.