क्या मुझे एप्लिकेशन स्तर की घटनाओं का वर्णन करने के लिए HTTP स्थिति कोड का उपयोग करना चाहिए


54

मेरे द्वारा निपटाए गए कई सर्वर HTTP 200 को उन अनुरोधों के लिए लौटाएंगे, जो ग्राहक को असफलता पर विचार करने के लिए चाहिए, शरीर में 'सफलता: असत्य' जैसी चीज के साथ।

यह मेरे लिए HTTP कोड के उचित कार्यान्वयन की तरह प्रतीत नहीं होता है, खासकर असफल प्रमाणीकरण के मामलों में। मैंने HTTP त्रुटि कोड को बहुत आसानी से पढ़ा है, जैसा कि '4xx' इंगित करता है कि अनुरोध को तब तक फिर से नहीं किया जाना चाहिए, जबकि '5xx' इंगित करता है कि अनुरोध मान्य हो सकता है या वापस नहीं लिया जा सकता है, लेकिन असफल रहा है। इस स्थिति में 200: लॉगिन विफल हो गया, या 200: उस फ़ाइल को नहीं ढूंढ सका, या 200: लापता पैरामीटर x, निश्चित रूप से गलत लगता है।

दूसरी ओर, मैं इस तर्क को देख सकता था कि '4xx' केवल अनुरोध के साथ एक संरचनात्मक मुद्दे को इंगित करना चाहिए। इसलिए यह 200: खराब उपयोगकर्ता / पासवर्ड को 401 अनधिकृत के बजाय वापस करने के लिए उचित है क्योंकि ग्राहक को अनुरोध करने की अनुमति है, लेकिन यह गलत होता है। इस तर्क को संक्षेप में प्रस्तुत किया जा सकता है, यदि सर्वर अनुरोध को संसाधित करने और सभी पर एक दृढ़ संकल्प करने में सक्षम था, तो प्रतिक्रिया कोड 200 होना चाहिए, और यह ग्राहक के ऊपर है कि वह आगे की जानकारी के लिए शरीर की जांच कर सके।

मूल रूप से, यह वरीयता का मामला लगता है। लेकिन यह असंतोषजनक है, इसलिए यदि किसी के पास कोई कारण है कि इनमें से एक भी प्रतिमान अधिक सही है, तो मैं जानना चाहूंगा।


9
success: falseतात्पर्य यह है कि अनुरोध विफल हो गया और आप इसे जानते हैं। यह 500 होना चाहिए। आपके खराब उपयोगकर्ता नाम / पासवर्ड की तरह कुछ 401 होगा। यह अस्पष्ट नहीं है।
पीट


4
यह उन सवालों में से एक है जो मुझे लगता है कि धार्मिक युद्धों को आमंत्रित कर सकते हैं। RESTful API के लिए, उत्तर स्पष्ट है, लेकिन अन्य प्रकार के API हैं जहाँ HTTP को एक ट्रांसपोर्ट लेयर के रूप में माना जाता है, और उन मामलों में, एप्लिकेशन त्रुटियों को उस लेयर पर ब्लीड नहीं किया जाना चाहिए।
रोबोट को

5
जब मुझे वास्तव में यकीन नहीं है कि 418 के साथ जाने के लिए http की स्थिति क्या है, तो यह हमेशा लुभावना है "मैं एक चायदानी हूँ।"
joshp

1
एक उदाहरण कई (बैचेड) अनुरोध और प्रतिक्रियाएं हैं । बैचिंग एक आराम की चीज नहीं है; लेकिन व्यावहारिक दक्षता चिंताओं को अक्सर लालित्य चिंताओं पर ध्यान केंद्रित करने के लिए कुछ समर्थन की आवश्यकता होती है।
रोंगोंग

जवाबों:


35

दिलचस्प सवाल।

असल में, हम ओएसआई परतों के अनुरूप चीजों को वर्गीकृत करने के लिए इसे सही तरीके से कम कर सकते हैं। HTTP को आमतौर पर Application Level प्रोटोकॉल के रूप में परिभाषित किया जाता है, और HTTP वास्तव में एक सामान्य क्लाइंट / सर्वर प्रोटोकॉल है।

हालाँकि, व्यवहार में, सर्वर लगभग हमेशा एक रिले करने वाला उपकरण होता है, और क्लाइंट एक वेब ब्राउज़र होता है, जो सामग्री की व्याख्या और प्रतिपादन के लिए जिम्मेदार होता है: सर्वर बस चीजों को एक मनमाने ढंग से एप्लिकेशन को पास करता है, और यह एप्लीकेशन उन मनमानी लिपियों को वापस भेजता है जो ब्राउज़र निष्पादित करने के लिए जिम्मेदार है। HTTP इंटरेक्शन स्वयं - अनुरोध / प्रतिक्रिया प्रपत्र, स्थिति कोड, और इसी तरह - अधिकतर अनुरोध है कि कैसे, अनुरोध, सेवा, और बिना संभव के रूप में कुशलता से मनमाने ढंग से सामग्री को प्रस्तुत करने का तरीका है। कई स्टेटस कोड और हेडर वास्तव में इन उद्देश्यों के लिए डिज़ाइन किए गए हैं।

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

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

इस दृष्टिकोण का अन्य लाभ, जो ध्यान देने योग्य है, यह है कि अनुप्रयोगों को आम तौर पर बोलना चाहिए, एक अंतर्निहित परिवहन प्रोटोकॉल (तार्किक दृष्टिकोण से) पर निर्भर नहीं होना चाहिए। HTTP स्वयं अतीत में बदल गया है, और अब हम SPDY के बाद HTTP 2 में किक मार रहे हैं। यदि आप अपने ऐप को HTTP फंक्शनलिटी प्लगइन से अधिक नहीं देखते हैं, तो हो सकता है कि नई अवसंरचनाएँ लेने पर आप वहाँ अटक जाएँ।


8
बहुत ही खुशनुमा। यहां सबसे मजबूत तर्क HTTP स्थिति कोड और आपके ऐप के रिटर्न मूल्यों के बीच (प्रतिबाधा) बेमेल है। यह लंबे समय तक दुःस्वप्न बन सकता है। इसके अलावा, मैं परिवहन (HTTP) और पेलोड (ऐप डेटा) के बीच चिंताओं के अलगाव का समर्थन करता हूं। यदि आप किसी सेवा समापन बिंदु के URL को गलत करते हैं, तो आपको 404 मिलते हैं। यदि आप किसी गैर-मौजूद आइटम के लिए सेवा पूछते हैं, तो आपको एक ऐप-विशिष्ट संदेश मिलता है (शायद अतिरिक्त जानकारी के साथ आप समस्या को हल करने के लिए उपयोग कर सकते हैं)।

2
यदि आप URL गलत करते हैं, तो आप सही सर्वर पर भी समाप्त नहीं हो सकते हैं, और तब कुछ भी हो सकता है।
gnasher729 12

यह एक अच्छी तरह से सूक्ष्म रूप है। मुझे लगता है कि HTTP का छद्म-परिवहन परत बनने का मुद्दा एक दृढ़ संकल्प बनाने के साथ वास्तविक समस्या है। मैं अक्सर इस सवाल में खुद को चलाता हूं जब आपके पास एक नाज़ेक्स या एपाचे सर्वर होता है जो एक नोडज सर्वर को समीप करता है, जहां प्रॉक्सी के पास इन कोडों को भेजने के लिए पहले से ही नियम हैं, और यह सवाल बनता है कि क्या बैकएंड के लिए मानक के अनुरूप होना उचित है। उन मामलों में से कुछ में एक त्रुटि कारण नहीं भेजने के लिए एक डिज़ाइन कारण हो सकता है , क्योंकि nginx इसे 'बैकएंड डाउन' के रूप में व्याख्या कर सकता है।
कागन मैटसन

4
मैं सहमत हूँ। HTTP 200 प्रतिसाद में रिपोर्ट की जा रही एप्लिकेशन-लेयर त्रुटि के बारे में कुछ भी गलत नहीं है। 200 इंगित करता है कि HTTP अनुरोध / प्रतिक्रिया स्वयं सफल थी, उस समय उसकी सामग्री या एप्लिकेशन-लेयर शब्दार्थ के बारे में कुछ भी कहे बिना।
मोनिका

22

यह सवाल थोड़ा राय आधारित है, लेकिन दोनों तरह से।

जिस तरह से मैं इसे देखता हूं, 200 "नरम त्रुटियों" की सेवा कर सकता है। जब एपीआई के निर्माण की बात आती है तो मैं इन और "कठिन त्रुटियों" के बीच अंतर करने की कोशिश करता हूं।

"सॉफ्ट एरर" को 200 के स्टेटस कोड के साथ परोसा जाएगा, लेकिन इसमें एक त्रुटि विवरण और एक सफल स्टेटस होगा false। "सॉफ्ट एरर" तभी होगा जब परिणाम "उम्मीद के मुताबिक" होगा, लेकिन सख्त अर्थों में सफलता नहीं।

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

उदाहरण के लिए, आपके पास खोज फ़ंक्शन के साथ API है, लेकिन खोज के दौरान, कोई परिणाम नहीं मिले हैं। यह गलत नहीं है, लेकिन यह "सफलता" भी नहीं है, न कि परिभाषा के सबसे सख्त अर्थ में।

उदाहरण JSON के रूप में स्वरूपित:

{
    "meta" {
        "success": false,
        "message": "Search yielded no results",
        "code": "NORESULTS"
    }
    "data": []
}

दूसरी ओर, "हार्ड एरर" को एक स्टेटस कोड के साथ परोसा जाएगा जो कि त्रुटि के लिए अनुशंसित है। उपयोगकर्ता लॉग इन नहीं है? - 403 / 401. विकृत इनपुट? - 400. सर्वर त्रुटि? - 50X। और इसी तरह।

फिर, यह थोड़ा राय-आधारित है। कुछ लोग सभी त्रुटियों को समान रूप से व्यवहार करना चाहते हैं, "कठिन त्रुटि" सब कुछ। खोजने पर कोई परिणाम नहीं मिला? यह एक 404 है! सिक्के के दूसरी तरफ, कोई खोज परिणाम नहीं? - यह अपेक्षित है, कोई त्रुटि नहीं।

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


2
वास्तव में, एपीआई-स्तर पर एक त्रुटि के रूप में वर्गीकृत करना एक जिज्ञासु निर्णय है। भले ही ग्राहक अपने विवेक पर, इसे उपयोगकर्ता-स्तर पर अप्रत्याशित रूप से वर्गीकृत कर सकता है।
डिडुप्लिकेटर

1
ऐसी कई चीजें हैं, जिन्हें फॉलो करना पड़ता है। यह सब एपीआई के कार्यान्वयन पर निर्भर करता है। यह फिर से है, थोड़ा सा राय-आधारित और यह भी कि एपीआई "सफलता" और / या "त्रुटि" के रूप में क्या परिभाषित करता है। "success": false-Flag एक अधिक है संकेत implementer के लिए है कि कुछ हो रहा है। आमतौर पर इसे आंतरिक स्थिति कोड के साथ जाना चाहिए । या तो "code": "NORESULTS"एक संख्यात्मक कोड - एपीआई के निर्माता जो भी। यह ज्यादातर वहां होता है, जो कोई भी एपीआई को लागू करता है, वह सर्वर पर क्या हुआ, इसके बारे में जानकारी घटा सकता है।
22

15

एपीआई के दो पहलू हैं: एपीआई को लागू करने का प्रयास, और एपीआई का सही उपयोग करने के लिए सभी ग्राहकों का प्रयास।

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

एपीआई को डिजाइन करना, आपको यह देखना चाहिए कि क्लाइंट के लिए प्रक्रिया करना सबसे आसान क्या है। यदि क्लाइंट एक अच्छी तरह से गठित अनुरोध भेजता है, और आप वह कर सकते हैं जो अनुरोध आपसे करने के लिए कहता है, तो आपको 200 रेंज में जवाब देना चाहिए (कुछ मामले हैं जहां उस सीमा में 200 के अलावा एक संख्या उपयुक्त है)।

यदि क्लाइंट पूछता है "मुझे सभी रिकॉर्ड दें जैसे ...", और शून्य हैं, तो सफलता के साथ 200 और शून्य रिकॉर्ड की एक सरणी पूरी तरह से उपयुक्त है। आपके द्वारा उल्लिखित मामले:

"लॉगिन विफल" आमतौर पर एक 401 होना चाहिए। "फ़ाइल नहीं मिल रही है" एक 404 होना चाहिए। "लापता पैरामीटर x" 500 के आसपास कुछ होना चाहिए (वास्तव में, एक 400 अगर सर्वर यह कहता है कि अनुरोध खराब है, और 500 अगर सर्वर मेरे अनुरोध से पूरी तरह से भ्रमित है और पता नहीं क्या चल रहा है)। इन मामलों में 200 वापस करना व्यर्थ है। यह सिर्फ एक ग्राहक के लेखक के रूप में मतलब है, मैं सिर्फ स्थिति कोड को नहीं देख सकता, मुझे उत्तर का भी अध्ययन करना होगा। मैं बस "स्टेटस 200, बढ़िया नहीं कह सकता, यहाँ डेटा है"।

विशेष रूप से "पैरामीटर लापता" - यह ऐसा कुछ नहीं है जिसे मैं कभी भी संभालूंगा । इसका मतलब मेरा अनुरोध गलत है। यदि मेरा अनुरोध गलत है, तो मेरे पास उस गलत अनुरोध को ठीक करने के लिए कोई वापसी नहीं है - मैं शुरू करने के लिए एक सही अनुरोध भेजूंगा। अब मैं इसे संभालने के लिए मजबूर हूं। मुझे एक 200 मिलता है और यह जांचना पड़ता है कि क्या कोई उत्तर "पैरामीटर लापता" है। यह अद्भुत है।

अंत में, कई अलग-अलग स्थितियों को संभालने के लिए एक दर्जन या दो स्थिति कोड हैं, और आपको उनका उपयोग करना चाहिए।


3
जब एक एपीआई से कनेक्ट होता है, तो मैं व्यक्तिगत रूप से एक मान्य समापन बिंदु से कनेक्ट करते समय 'फाइल नहीं मिली' पर 200 प्राप्त करूंगा, क्योंकि तब मेरे HTTP हैंडलिंग को उस परत में खून बहाना नहीं पड़ता है जो इसके ऊपर एपीआई को संभालता है।
whatsisname

4
"मिसिंग पैरामीटर x" एक 400 BAD_REQUEST होना चाहिए क्योंकि यह क्लाइंट कुछ गलत कर रहा है। 500 INTERNAL_SERVER_ERROR उन मामलों के लिए आरक्षित होना चाहिए जहां सर्वर गलत काम कर रहा है। 500 का तात्पर्य है कि ग्राहक फिर से प्रयास करने में सक्षम हो सकता है। 400 का तात्पर्य है कि किसी को ग्राहक को ठीक करना चाहिए।
रोबोट को

1
यदि आप एक RESTful इंटरफ़ेस लिख रहे हैं, तो URL एक विशिष्ट ऑब्जेक्ट की पहचान करता है और इसलिए 404 उपयुक्त है। यह वैचारिक /customers/premium/johndoe.jsonरूप से एक ग्राहक को संदर्भित करता है जो डेटाबेस में नहीं है और यदि /files/morefiles/customers.htmlएक पेज पर संदर्भित है तो फाइलसिस्टम पर नहीं।
रोबोट

@whatsisname जो आप कह रहे हैं वह समझ में आता है क्योंकि यह स्पष्ट नहीं है कि यह समापन बिंदु है जो खराब है या संसाधन मौजूद नहीं है। आप यह भी तर्क दे सकते हैं कि क्या समापन बिंदु वैध है या नहीं, उस पते पर कोई संसाधन मौजूद नहीं है इसलिए 404दोनों मामलों में यह सही है।
पीट

2
एक बात जिसका मैंने उल्लेख नहीं किया है, वह यह है कि जब आप HTTP स्टेटस कोड्स पर अनुप्रयोग त्रुटियों को देखते हैं, तो आप जानकारी खो सकते हैं। यदि ऐप सिर्फ 404 देता है और कुछ नहीं, तो आप यह नहीं जानते कि क्या यह इसलिए था क्योंकि आपका एपीआई 404 था, या क्योंकि सर्वर फ़ाइल नहीं खोज सका। यह आपके डीबगिंग में एक अतिरिक्त चरण जोड़ सकता है।
AmadeusDrZaius
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.