REST API में संग्रह में किसी मौजूदा आइटम को जोड़ने के लिए सबसे अच्छा पैटर्न क्या है?


23

मैं एक व्यावहारिक REST API डिज़ाइन कर रहा हूं और एक संग्रह में मौजूदा संस्थाओं को जोड़ने के लिए सबसे अच्छा पर थोड़ा अटक गया हूं। मेरे डोमेन मॉडल में एक परियोजना शामिल है जिसमें साइटों का एक संग्रह है। यह एक सख्त कई-से-कई संबंध है और मुझे एक इकाई बनाने की कोई आवश्यकता नहीं है जो स्पष्ट रूप से संबंध (यानी प्रोजेक्टसाइट) को मॉडल करता है।

मेरा एपीआई उपभोक्ताओं को एक परियोजना में एक मौजूदा साइट जोड़ने की अनुमति देगा। जहां मैं लटका हुआ हूं, केवल वही डेटा है जिसकी मुझे वास्तव में जरूरत है ProjectId और SiteId। मेरा प्रारंभिक विचार था:

1. POST myapi/projects/{projectId}/sites/{siteId}

लेकिन मैंने भी सोचा

2. POST myapi/projects/{projectId}/sites

JSON सामग्री के रूप में भेजी गई साइट इकाई के साथ।

विकल्प 1 सरल है और काम करता है, लेकिन यह बिल्कुल सही नहीं लगता है, और मेरे पास अन्य रिश्ते हैं जो इस पैटर्न का पालन नहीं कर सकते हैं, इसलिए यह मेरे एपीआई में असंगतता जोड़ता है।

विकल्प 2 बेहतर लगता है लेकिन दो चिंताओं की ओर जाता है:

  • यदि एक नई साइट पोस्ट की गई है तो क्या मुझे एक साइट बनानी चाहिए या एक अपवाद फेंकना चाहिए (SiteId = 0)?
  • क्योंकि मुझे संबंध बनाने के लिए केवल ProjectId और SiteId की आवश्यकता है, साइट को अन्य गुणों के लिए गलत या अनुपलब्ध डेटा के साथ पोस्ट किया जा सकता है।

एक 3 विकल्प केवल संबंध बनाने और हटाने के लिए एक सरल समापन बिंदु प्रदान करना है। यह एंडपॉइंट एक JSON पेलोड की उम्मीद करेगा जिसमें सिर्फ ProjectId और SiteId होंगे।

तुम क्या सोचते हो?


2
इन्हें भी देखें: stackoverflow.com/questions/2001773/…
रोरी हंटर

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

आपका पहला विकल्प ठीक है, हालांकि मैं POST के बजाय PUT का उपयोग करूंगा क्योंकि ग्राहक को संग्रह में जोड़े जा रहे पहचान के नियंत्रण में है। विकल्प 2 के साथ आपकी पहली चिंता पूरी तरह से आप पर है, यदि आप नई साइट नहीं चाहते हैं, तो अपवाद न फेंकें, लेकिन 4xx कोड में से एक को वापस कर दें। आपकी दूसरी चिंता न तो यहां है और न ही है। जब तक आप परिवर्धन की अनुमति नहीं देते, तब तक आपको पूरी साइट पोस्ट नहीं करनी चाहिए। किसी मौजूदा साइट को जोड़ने के लिए केवल आईडी होनी चाहिए क्योंकि आप साइट को संशोधित कर रहे हैं लेकिन केवल "प्रोजेक्टसाइट" संग्रह (भले ही आप इसके लिए एक अलग संसाधन न बनाएं)।
मार्जन वेनमा

जवाबों:


14

POST "परिशिष्ट" क्रिया है, और "प्रसंस्करण" क्रिया भी है। PUT "क्रिएट / अपडेट" क्रिया है (ज्ञात पहचानकर्ताओं के लिए), और लगभग यहाँ सही विकल्प की तरह दिखता है, क्योंकि पूर्ण लक्ष्य URI ज्ञात है। projectIdऔर siteIdपहले से ही मौजूद है, इसलिए आपको एक नई आईडी बनाने के लिए "एक संग्रह के लिए पोस्ट" करने की आवश्यकता नहीं है।

PUT के साथ समस्या यह है कि इसके लिए शरीर को उस संसाधन का प्रतिनिधित्व होना चाहिए जो आप PUTting कर रहे हैं। लेकिन यहां आशय यह है कि साइट संसाधन को अपडेट करने के बजाय "प्रोजेक्ट / साइट्स" संग्रह संसाधन में जोड़ा जाए।

यदि कोई व्यक्ति किसी मौजूदा साइट का पूर्ण JSON प्रतिनिधित्व करता है तो क्या होगा? क्या आपको संग्रह को अद्यतन करना चाहिए और वस्तु को ? आप इसका समर्थन कर सकते हैं, लेकिन ऐसा लगता है कि यह इरादा नहीं है। जैसा कि आपने कहा,

एकमात्र डेटा जो मुझे वास्तव में चाहिए वह है ProjectId और SiteId

बल्कि, मैं पोस्ट करने की कोशिश करूँगा siteId संग्रह लिए , और POST के "परिशिष्ट" और "प्रक्रिया" प्रकृति पर भरोसा :

पोस्ट myapi / परियोजनाओं / {projectId} / साइटों

{"आईडी": '...'}

चूंकि आप साइट संग्रह संसाधन को संशोधित कर रहे हैं, न कि साइट संसाधन , आप चाहते हैं कि यूआरआई। POST "परिशिष्ट / प्रक्रिया" को जान सकता है और उस आईडी के साथ तत्व को प्रोजेक्ट के साइट संग्रह में जोड़ सकता है।

यह अभी भी JSON के बाहर और आईडी को छोड़ कर परियोजना के लिए एकदम नए साइट बनाने के लिए खुला छोड़ देता है। "नो आईडी" == "स्क्रैच से बनाएं"। लेकिन अगर संग्रह URI को एक आईडी और कुछ नहीं मिलता है, तो यह बहुत स्पष्ट है कि क्या होना चाहिए।

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


मुझे विश्वास है कि विश्वास POST बनाने के लिए है और PUT अपडेट के लिए है, लेकिन आपका निष्कर्ष वह है जहां मैं कल समाप्त हुआ था। अच्छी बात यह है कि वेब एपीआई में विशेषता रूटिंग के लिए धन्यवाद, मेरे पास एक प्रोजेक्टसाइट नियंत्रक में कोड है ताकि कोड अच्छी तरह से व्यवस्थित हो।
जेमी इडे

मुझे लगता है कि आपको POSTइसके बजाय PUTया PATCHयहां उपयोग करने के लिए परिभाषित कारण यह है कि आपके पास संसाधन Siteमें डालने के लिए पूरी इकाई नहीं है sites। आपके पास केवल आईडी है, जिसे संग्रह में जोड़ने के लिए इसके प्रसंस्करण की आवश्यकता है।
क्रश करें

4

हम इस तरह से सामान के लिए Patchविधि का उपयोग करते हैं । आप जो करना चाहते हैं, उसमें एक साइट जोड़ने के लिए एक मौजूदा परियोजना को संशोधित करें।

तो ऐसा कुछ काम करेगा

PATCH myapi/projects/{id} 

अनुरोध निकाय में JSON / JSONArray के रूप में साइट (एस) इकाई के साथ।

इस तरह से आप प्रोजेक्ट के विभिन्न हिस्सों को संशोधित करने के लिए एक ही URL का उपयोग कर सकते हैं - यदि आपके पास आवश्यक है - तो संसाधन के इस आंशिक संशोधन को संभालने के लिए कार्यान्वयन में आपका कोड पर्याप्त बुद्धिमान होना चाहिए।


दिलचस्प दृष्टिकोण। मेरे पास एक "अमीर" (यानी अत्यधिक आश्रित) पुराना डोमेन मॉडल है और प्रोजेक्ट में विशेष रूप से कई संग्रह हैं जो इसे लटकाए हुए हैं। अनुरोध में निकाले जा रहे इकाई प्रकार का पता लगाना एक चुनौती होगी और यह मेरे व्यावहारिक लक्ष्य के अनुकूल नहीं है।
जेमी इडे

एक चुनौती क्यों? यदि आपके पास उन प्रतिबंध हैं, तो आप हमेशा एक JSON का उपयोग कर सकते हैं जो स्पष्ट करता है कि यह क्या भेज रहा है ... जैसे {"sites": [], "other-stuff": {}}, आप तब अपने कोड को उन सभी "सबजन्स" को बहुत आसानी से संभालने के लिए शाखा कर सकते हैं। यह वास्तव में आपकी विशिष्ट समस्या पर निर्भर करता है, लेकिन मैं अभी भी PATCH का उपयोग करने की सिफारिश करूंगा क्योंकि यह विशेष रूप से इस तरह की चीजों के लिए डिज़ाइन किया गया है।
जुआन

मेरे द्वारा देखे गए डाउनसाइड 1 हैं) एपीआई स्पष्ट रूप से संवाद नहीं करता है कि कौन सा संग्रह परिवर्तन की अनुमति देता है; 2) वेब एपीआई पैरामीटर बाइंडिंग का लाभ नहीं उठा सकता है; 3) बड़ा स्विच या अगर बयान।
जेमी इडे

मैंने पैच विधि कहीं और कभी नहीं देखी है
निमचम्पस्की

PATCHकिसी इकाई की ओर इशारा करने वाले आईडी के बजाए, पूर्ण इकाई को इसके मूल्य के रूप में पारित करने की अपेक्षा नहीं करेंगे ?
क्रश करें
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.