परिवर्तन के लिए दूरदर्शिता के साथ बाहरी अनुप्रयोगों के लिए एक एपीआई डिजाइन करने की कोशिश करना आसान नहीं है, लेकिन थोड़ा सोचा हुआ आगे जीवन को बाद में आसान बना सकता है। मैं एक ऐसी योजना स्थापित करने की कोशिश कर रहा हूं, जो भविष्य में होने वाले बदलावों का समर्थन करेगी, जबकि पूर्व संस्करण संचालकों को पीछे छोड़ते हुए संगत।
इस लेख पर प्राथमिक चिंता यह है कि किसी दिए गए उत्पाद / कंपनी के लिए सभी परिभाषित समापन बिंदुओं के लिए किस पैटर्न का पालन किया जाना चाहिए।
आधार योजना
के आधार URL टेम्पलेट को देखते हुए https://rest.product.com/
मैंने यह सुनिश्चित किया है कि सभी सेवाएं /api
साथ-साथ चलें /auth
और अन्य गैर-शेष आधारित समापन बिंदु जैसे /doc
। इसलिए मैं बेस एंडपॉइंट्स को इस प्रकार स्थापित कर सकता हूं:
https://rest.product.com/api/...
https://rest.product.com/auth/login
https://rest.product.com/auth/logout
https://rest.product.com/doc/...
सेवा समापन बिंदु
अब स्वयं समापन बिंदुओं के लिए। चिंता के बारे में POST
, GET
, DELETE
इस लेख का मूल उद्देश्य नहीं है और उन कार्यों के लिए खुद पर चिंता का विषय है।
एंडपॉइंट को नामस्थान और कार्यों में विभाजित किया जा सकता है। प्रत्येक क्रिया को रिटर्न प्रकार या आवश्यक मापदंडों में मूलभूत परिवर्तनों का समर्थन करने के लिए स्वयं को प्रस्तुत करना चाहिए।
एक काल्पनिक चैट सेवा लेना जहां पंजीकृत उपयोगकर्ता संदेश भेज सकते हैं हमारे पास निम्नलिखित समापन बिंदु हो सकते हैं:
https://rest.product.com/api/messages/list/{user}
https://rest.product.com/api/messages/send
अब भविष्य के एपीआई परिवर्तनों के लिए संस्करण समर्थन जोड़ने के लिए जो टूट सकता है। हम या तो के बाद संस्करण हस्ताक्षर जोड़ सकता है /api/
या बाद /messages/
। send
समापन बिंदु को देखते हुए हम फिर v1 के लिए निम्नलिखित हो सकते हैं।
https://rest.product.com/api/v1/messages/send
https://rest.product.com/api/messages/v1/send
तो मेरा पहला सवाल यह है कि संस्करण पहचानकर्ता के लिए अनुशंसित स्थान क्या है?
नियंत्रक कोड का प्रबंधन
इसलिए अब हमने स्थापित किया है कि हमें पूर्व संस्करणों का समर्थन करने की आवश्यकता है ताकि हम किसी भी तरह से नए संस्करणों में से प्रत्येक के लिए कोड को संभाल सकें, जो समय के साथ घट सकता है। मान लें कि हम जावा में एंडपॉइंट लिख रहे हैं तो हम इसे पैकेज के माध्यम से प्रबंधित कर सकते हैं।
package com.product.messages.v1;
public interface MessageController {
void send();
Message[] list();
}
इसका यह फायदा है कि सभी कोड को नामस्थानों के माध्यम से अलग कर दिया गया है, जहां किसी भी परिवर्तन को बदलने का मतलब होगा कि सेवा समापन बिंदु की एक नई प्रतिलिपि। इसका दोष यह है कि सभी कोड को कॉपी करने की जरूरत है और बग फिक्स को नए और पूर्व संस्करणों में लागू करने की आवश्यकता है जिसे प्रत्येक कॉपी के लिए लागू / परीक्षण किया जाना है।
एक और दृष्टिकोण प्रत्येक समापन बिंदु के लिए हैंडलर बनाना है।
package com.product.messages;
public class MessageServiceImpl {
public void send(String version) {
getMessageSender(version).send();
}
// Assume we have a List of senders in order of newest to oldest.
private MessageSender getMessageSender(String version) {
for (MessageSender s : senders) {
if (s.supportsVersion(version)) {
return s;
}
}
}
}
यह अब प्रत्येक समापन बिंदु के लिए संस्करण को अलग करता है और बग फिक्स को केवल एक बार लागू करने की आवश्यकता वाले अधिकांश मामलों में संगत करता है, लेकिन इसका मतलब यह है कि हमें इसका समर्थन करने के लिए प्रत्येक व्यक्ति के समापन बिंदु के लिए थोड़ा अधिक काम करने की आवश्यकता है।
तो मेरा दूसरा सवाल है "पूर्व संस्करणों का समर्थन करने के लिए REST सेवा कोड डिजाइन करने का सबसे अच्छा तरीका क्या है।"