यह एक बहुत पुरानी पोस्ट है लेकिन मुझे एक ऐसी ही समस्या का सामना करना पड़ा है और मैं अपना अनुभव आप लोगों के साथ साझा करना चाहूंगा।
मैं बाकी APIs के साथ माइक्रोसॉर्फ़ आर्किटेक्चर का निर्माण कर रहा हूं। मेरे पास कुछ बाकी जीईटी सेवाएं हैं, वे अनुरोध मापदंडों के आधार पर बैक-एंड सिस्टम से डेटा एकत्र करते हैं।
मैंने बाकी एपीआई डिज़ाइन दस्तावेज़ों का पालन किया और मैंने क्लाइंट को एक सही JSON त्रुटि संदेश के साथ HTTP 404 वापस भेजा जब कोई डेटा नहीं था जो क्वेरी शर्तों के लिए संरेखित था (उदाहरण के लिए शून्य रिकॉर्ड चुना गया था)।
जब क्लाइंट के पास वापस भेजने के लिए कोई डेटा नहीं था, तो मैंने "नॉट फाउंड" के कारण के बारे में क्लाइंट को सूचित करने के लिए आंतरिक त्रुटि कोड, आदि के साथ एक परिपूर्ण JSON संदेश तैयार किया और इसे HTTP 404 के साथ क्लाइंट को वापस भेज दिया गया। ठीक काम करता है।
बाद में मैंने एक आराम एपीआई क्लाइंट क्लास बनाया है जो HTTP संचार से संबंधित कोड को छिपाने के लिए एक आसान सहायक है और मैंने अपने कोड से अपने बाकी एपीआई को कॉल करने पर हर समय इस सहायक का उपयोग किया है।
लेकिन मुझे भ्रामक अतिरिक्त कोड लिखने की आवश्यकता थी क्योंकि HTTP 404 में दो अलग-अलग कार्य थे:
- असली HTTP 404, जब दिए गए url में बाकी API उपलब्ध नहीं है, इसे एप्लिकेशन सर्वर या वेब-सर्वर द्वारा फेंक दिया जाता है, जहां बाकी API एप्लिकेशन चलता है
- क्लाइंट को HTTP 404 वापस मिल जाता है और जब क्वेरी की स्थिति के आधार पर डेटाबेस में कोई डेटा नहीं होता है।
महत्वपूर्ण: मेरा बाकी एपीआई त्रुटि हैंडलर पकड़ता है सभी अपवाद बैक-एंड सेवा में दिखाई देते हैं जिसका मतलब है कि किसी भी त्रुटि के मामले में मेरा बाकी एपीआई हमेशा संदेश विवरण के साथ एक परिपूर्ण JSON संदेश के साथ लौटता है।
यह मेरे क्लाइंट सहायक विधि का पहला संस्करण है जो दो अलग-अलग HTTP 404 प्रतिक्रिया को संभालता है:
public static String getSomething(final String uuid) {
String serviceUrl = getServiceUrl();
String path = "user/" + , uuid);
String requestUrl = serviceUrl + path;
String httpMethod = "GET";
Response response = client
.target(serviceUrl)
.path(path)
.request(ExtendedMediaType.APPLICATION_UTF8)
.get();
if (response.getStatus() == Response.Status.OK.getStatusCode()) {
// HTTP 200
return response.readEntity(String.class);
} else {
// confusing code comes here just because
// I need to decide the type of HTTP 404...
// trying to parse response body
try {
String responseBody = response.readEntity(String.class);
ObjectMapper mapper = new ObjectMapper();
ErrorInfo errorInfo = mapper.readValue(responseBody, ErrorInfo.class);
// re-throw the original exception
throw new MyException(errorInfo);
} catch (IOException e) {
// this is a real HTTP 404
throw new ServiceUnavailableError(response, requestUrl, httpMethod);
}
// this exception will never be thrown
throw new Exception("UNEXPECTED ERRORS, BETTER IF YOU DO NOT SEE IT IN THE LOG");
}
लेकिन , क्योंकि मेरा जावा या जावास्क्रिप्ट क्लाइंट दो तरह का HTTP 404 प्राप्त कर सकता है, मुझे किसी तरह HTTP 404 के मामले में प्रतिक्रिया की बॉडी की जांच करने की आवश्यकता है। यदि मैं प्रतिक्रिया निकाय को पार्स कर सकता हूं, तो मुझे यकीन है कि मुझे एक प्रतिक्रिया वापस मिल गई है, जहां था ग्राहक को वापस भेजने के लिए कोई डेटा नहीं।
यदि मैं उस प्रतिक्रिया को पार्स नहीं कर पा रहा हूं, जिसका अर्थ है कि मुझे वेब सर्वर से एक वास्तविक HTTP 404 मिला है (बाकी एपीआई एप्लिकेशन से नहीं)।
यह बहुत भ्रामक है और क्लाइंट एप्लिकेशन को HTTP 404 के वास्तविक कारण की जांच करने के लिए हमेशा अतिरिक्त पार्सिंग करने की आवश्यकता होती है।
ईमानदारी से मुझे यह समाधान पसंद नहीं है। यह भ्रामक है, ग्राहकों को हर समय अतिरिक्त बकवास कोड जोड़ने की आवश्यकता है।
इसलिए मैंने इस दो अलग-अलग परिदृश्यों में HTTP 404 का उपयोग करने के बजाय यह निर्णय लिया कि मैं निम्नलिखित कार्य करूंगा:
- मैं अपने बाकी एप्लिकेशन में अब HTTP 404 को एक प्रतिक्रिया HTTP कोड के रूप में उपयोग नहीं कर रहा हूं।
- मैं HTTP 404 के बजाय HTTP 204 (नो कंटेंट) का उपयोग करने जा रहा हूं।
उस स्थिति में क्लाइंट कोड अधिक सुरुचिपूर्ण हो सकता है:
public static String getString(final String processId, final String key) {
String serviceUrl = getServiceUrl();
String path = String.format("key/%s", key);
String requestUrl = serviceUrl + path;
String httpMethod = "GET";
log(requestUrl);
Response response = client
.target(serviceUrl)
.path(path)
.request(ExtendedMediaType.APPLICATION_JSON_UTF8)
.header(CustomHttpHeader.PROCESS_ID, processId)
.get();
if (response.getStatus() == Response.Status.OK.getStatusCode()) {
return response.readEntity(String.class);
} else {
String body = response.readEntity(String.class);
ObjectMapper mapper = new ObjectMapper();
ErrorInfo errorInfo = mapper.readValue(body, ErrorInfo.class);
throw new MyException(errorInfo);
}
throw new AnyServerError(response, requestUrl, httpMethod);
}
मुझे लगता है कि यह इस मुद्दे को बेहतर तरीके से संभालता है।
यदि आपके पास कोई बेहतर उपाय है तो कृपया हमारे साथ साझा करें।