नोट : जब मैंने पहली बार REST के बारे में पढ़ते हुए समय बिताया, तो idempotence सही होने की कोशिश करने के लिए एक भ्रामक अवधारणा थी। मुझे अभी भी अपने मूल उत्तर में यह ठीक नहीं लगा, जैसा कि आगे की टिप्पणी (और जेसन होएगर के उत्तर ) ने दिखाया है। थोड़ी देर के लिए, मैंने इस उत्तर को बड़े पैमाने पर अपडेट करने का विरोध किया है, जेसन को प्रभावी ढंग से रोकने के लिए, लेकिन मैं इसे अब संपादित कर रहा हूं क्योंकि, ठीक है, मुझे (टिप्पणियों में) पूछा गया था।
मेरे उत्तर को पढ़ने के बाद, मेरा सुझाव है कि आप इस प्रश्न का जेसन होइटर का उत्कृष्ट उत्तर भी पढ़ें , और मैं केवल जेसन से चोरी किए बिना अपने उत्तर को बेहतर बनाने का प्रयास करूंगा।
क्यों है PUT सुस्पष्ट?
जैसा कि आपने अपने RFC 2616 प्रशस्ति पत्र में उल्लेख किया है, PUT को बेरोजगार माना जाता है। जब आप किसी संसाधन को प्राप्त करते हैं, तो ये दो धारणाएं खेल में होती हैं:
आप एक इकाई की बात कर रहे हैं, किसी संग्रह की नहीं।
आपके द्वारा आपूर्ति की जाने वाली इकाई पूर्ण ( संपूर्ण इकाई) है।
आइए आपके एक उदाहरण को देखें।
{ "username": "skwee357", "email": "skwee357@domain.com" }
यदि आप इस दस्तावेज़ को पोस्ट करते हैं /users
, जैसा कि आप सुझाव देते हैं, तो आप इस तरह के रूप में एक इकाई वापस पा सकते हैं
## /users/1
{
"username": "skwee357",
"email": "skwee357@domain.com"
}
यदि आप इस इकाई को बाद में संशोधित करना चाहते हैं, तो आप PUT और PATCH के बीच चयन करें। एक PUT इस तरह दिख सकता है:
PUT /users/1
{
"username": "skwee357",
"email": "skwee357@gmail.com" // new email address
}
आप पाच का उपयोग करके इसे पूरा कर सकते हैं। यह इस तरह लग सकता है:
PATCH /users/1
{
"email": "skwee357@gmail.com" // new email address
}
आपको इन दोनों के बीच अंतर दिखाई देगा। PUT में इस उपयोगकर्ता के सभी पैरामीटर शामिल थे, लेकिन PATCH में केवल वही शामिल था जिसे संशोधित किया जा रहा था ( email
)।
PUT का उपयोग करते समय, यह माना जाता है कि आप पूरी इकाई भेज रहे हैं, और वह पूर्ण इकाई किसी भी मौजूदा इकाई को उस URI में बदल देती है । उपरोक्त उदाहरण में, PUT और PATCH एक ही लक्ष्य पूरा करते हैं: वे दोनों इस उपयोगकर्ता के ईमेल पते को बदलते हैं। लेकिन PUT इसे पूरी इकाई को बदलकर संभालता है, जबकि PATCH केवल उन फ़ील्ड्स को अपडेट करता है जो दूसरों को अकेला छोड़ रहे थे।
चूंकि PUT अनुरोधों में संपूर्ण इकाई शामिल होती है, यदि आप एक ही अनुरोध को बार-बार जारी करते हैं, तो इसका हमेशा एक ही परिणाम होना चाहिए (आपके द्वारा भेजा गया डेटा अब इकाई का संपूर्ण डेटा है)। इसलिए पीयूटी बेकार है।
PUT का गलत उपयोग करना
यदि आप एक PUT अनुरोध में उपरोक्त PATCH डेटा का उपयोग करते हैं तो क्या होगा?
GET /users/1
{
"username": "skwee357",
"email": "skwee357@domain.com"
}
PUT /users/1
{
"email": "skwee357@gmail.com" // new email address
}
GET /users/1
{
"email": "skwee357@gmail.com" // new email address... and nothing else!
}
(मैं इस सवाल के प्रयोजनों के लिए मान रहा हूं कि सर्वर के पास कोई विशिष्ट आवश्यक फ़ील्ड नहीं है, और ऐसा करने की अनुमति देगा ... जो वास्तव में ऐसा नहीं हो सकता है।)
चूंकि हमने PUT का उपयोग किया, लेकिन केवल आपूर्ति की email
, अब इस इकाई में केवल एक चीज है। इससे डेटा हानि हुई है।
उदाहरण के लिए यहाँ उदाहरण है - वास्तव में ऐसा कभी मत करो। यह PUT अनुरोध तकनीकी रूप से उदासीन है, लेकिन इसका मतलब यह नहीं है कि यह एक भयानक, टूटा हुआ विचार नहीं है।
PATCH को कैसे बनाया जा सकता है?
उपर्युक्त उदाहरण में, PATCH आलसी था । आपने एक परिवर्तन किया, लेकिन यदि आपने बार-बार एक ही परिवर्तन किया, तो यह हमेशा एक ही परिणाम देगा: आपने ईमेल पते को नए मूल्य में बदल दिया।
GET /users/1
{
"username": "skwee357",
"email": "skwee357@domain.com"
}
PATCH /users/1
{
"email": "skwee357@gmail.com" // new email address
}
GET /users/1
{
"username": "skwee357",
"email": "skwee357@gmail.com" // email address was changed
}
PATCH /users/1
{
"email": "skwee357@gmail.com" // new email address... again
}
GET /users/1
{
"username": "skwee357",
"email": "skwee357@gmail.com" // nothing changed since last GET
}
मेरा मूल उदाहरण, सटीकता के लिए तय किया गया
मेरे पास मूल रूप से ऐसे उदाहरण थे जो मुझे लगा कि गैर-बेरोजगारी दिखा रहे हैं, लेकिन वे भ्रामक / गलत थे। मैं उदाहरणों को रखने जा रहा हूं, लेकिन एक अलग चीज को चित्रित करने के लिए उनका उपयोग कर रहा हूं: एक ही इकाई के खिलाफ कई PATCH दस्तावेज, विभिन्न विशेषताओं को संशोधित करते हुए, PATCHes को गैर-बेरोजगार नहीं बनाते हैं।
मान लीजिए कि पिछले कुछ समय में, एक उपयोगकर्ता जोड़ा गया था। यह वह अवस्था है जिससे आप शुरू कर रहे हैं।
{
"id": 1,
"name": "Sam Kwee",
"email": "skwee357@olddomain.com",
"address": "123 Mockingbird Lane",
"city": "New York",
"state": "NY",
"zip": "10001"
}
एक पैट के बाद, आपके पास एक संशोधित इकाई है:
PATCH /users/1
{"email": "skwee357@newdomain.com"}
{
"id": 1,
"name": "Sam Kwee",
"email": "skwee357@newdomain.com", // the email changed, yay!
"address": "123 Mockingbird Lane",
"city": "New York",
"state": "NY",
"zip": "10001"
}
यदि आप अपने पैट को बार-बार लागू करते हैं, तो आपको एक ही परिणाम प्राप्त होता रहेगा: ईमेल को नए मूल्य में बदल दिया गया था। A अंदर जाता है, A बाहर आता है, इसलिए यह एक आदर्श है।
एक घंटे बाद, जब आप कुछ कॉफी बनाने और विराम लेने के लिए गए थे, तो कोई और व्यक्ति अपने पैट के साथ आता है। ऐसा लगता है कि डाकघर कुछ बदलाव कर रहा है।
PATCH /users/1
{"zip": "12345"}
{
"id": 1,
"name": "Sam Kwee",
"email": "skwee357@newdomain.com", // still the new email you set
"address": "123 Mockingbird Lane",
"city": "New York",
"state": "NY",
"zip": "12345" // and this change as well
}
चूँकि पोस्ट ऑफिस का यह PATCH खुद को ईमेल से चिंतित नहीं करता है, केवल ज़िप कोड है, यदि इसे बार-बार लागू किया जाता है, तो इसे भी वही परिणाम मिलेगा: ज़िप कोड नए मूल्य पर सेट होता है। A अंदर जाता है, A बाहर आता है, इसलिए यह भी बेकार है।
अगले दिन, आप अपने पैट को फिर से भेजने का फैसला करते हैं।
PATCH /users/1
{"email": "skwee357@newdomain.com"}
{
"id": 1,
"name": "Sam Kwee",
"email": "skwee357@newdomain.com",
"address": "123 Mockingbird Lane",
"city": "New York",
"state": "NY",
"zip": "12345"
}
आपके पैच का वही प्रभाव पड़ता है जो कल था: इसने ईमेल पता सेट किया। A अंदर गया, A बाहर आया, इसलिए यह भी अच्छा है।
मेरे मूल उत्तर में मुझे क्या गलत लगा
मैं एक महत्वपूर्ण अंतर आकर्षित करना चाहता हूं (मेरे मूल उत्तर में कुछ गलत हो गया है)। कई सर्वर आपके संशोधन (यदि कोई हो) के साथ, नई इकाई स्थिति को वापस भेजकर आपके REST अनुरोधों का जवाब देंगे। इसलिए, जब आपको यह प्रतिक्रिया वापस मिलती है , तो यह आपके द्वारा कल वापस किए गए से अलग है , क्योंकि ज़िप कोड वह नहीं है जो आपको इस बार मिला है। हालाँकि, आपका अनुरोध केवल ईमेल के साथ, ज़िप कोड से संबंधित नहीं था। तो आपका PATCH दस्तावेज़ अभी भी बेकार है - PATCH में आपके द्वारा भेजा गया ईमेल अब इकाई पर ईमेल पता है।
तो जब PATCH बेकार नहीं है, तब?
इस प्रश्न के पूर्ण उपचार के लिए, मैं आपको फिर से जेसन होएगर के उत्तर का उल्लेख करता हूं । मैं बस इसे उस पर छोड़ने जा रहा हूं, क्योंकि मैं ईमानदारी से नहीं सोचता कि मैं इस हिस्से का जवाब पहले से बेहतर कर सकता हूं।