अद्यतन करने के लिए पैच बनाम PUT का उपयोग करके मैं जावा में एक नए आराम एपीआई पर विकास शुरू करने जा रहा हूं। मेरा प्रश्न पैच के उपयोग के बारे में है - क्यों?जावा रीस्ट एपीआई में, एक इकाई
POST http://localhost:8080/addresses
निम्नलिखित अनुरोध के साथ
:
कहना चलें, हम Address.java
public class Address {
@Id
private Long id
@NotNull
private String line1;
private String line2; //optional
@NotNull
private String city;
@NotNull
private String state;
}
नामक एक नया पता बनाने के लिए एक इकाई है, मैं इस http अनुरोध करना होगा
{
"line1" : "mandatory Address line 1",
"line2" : "optional Address line 2",
"city" : "mandatory City",
"state" : "cd"
}
मान लें कि बनाए गए रिकॉर्ड में आईडी 1
है@PostMapping(value = "/addresses")
public ResponseEntity<Address> create(@valid Address newAddress) {
addressRepo.save(newAddress);
}
@valid सुनिश्चित करेगा इकाई तालिका में डेटा भंडारण से पहले मान्य है:
इसी @RestController AddressResource.java इस विधि होगा।
अब मान लीजिए, मैं अपने अपार्टमेंट से ऊपर सड़क पर एक घर में जाता हूं। अगर मैं एक पैच उपयोग करें, यह अनुरोध पेलोड के साथ
PATCH http://localhost:8080/addresses/1
हो जाता है:
{
"line1" : "1234 NewAddressDownTheStreet ST",
"line2" : null
}
इसी @RestController तरीका होगा:
@PatchMapping(value = "/addresses/{id}")
public ResponseEntity<Address> patchAddress(@PathVariable Long id, Address partialAddress)
{
Address dbAddress = addressRepo.findOne(id);
if (partialAddress.getLine1() != null) {
dbAddress.setLine1(partialAddress.getLine1());
}
if (partialAddress.getLine2() != null) {
dbAddress.setLine2(partialAddress.getLine2());
}
if (partialAddress.getCity() != null) {
dbAddress.setCity(partialAddress.getCity());
}
if (partialAddress.getState() != null) {
dbAddress.setState(partialAddress.getState());
}
addressRepo.save(dbAddress)
}
अब अगर आप तालिका क्वेरी, जीता ' मेरा पता नहीं है?
"line1" : "1234 NewAddressDownTheStreet ST",
"line2" : "optional Address line 2", <-- INCORRECT. Should be null.
"city" : "mandatory City",
"state" : "cd"
जैसा देखा जा सकता है, उपर्युक्त अपडेट लाइन 2 के लिए गलत मान में परिणाम देते हैं। ऐसा इसलिए है क्योंकि जावा में एड्रेस क्लास में सभी इंस्टेंस चर को प्रारंभिक (या डिफ़ॉल्ट प्रारंभिक मान अगर वे प्राइमेटिव होते हैं) को प्रारंभ किया जाता है जब कक्षा को तत्काल किया जाता है। इसलिए डिफ़ॉल्ट मान से लाइन 2 को बदले जाने के बीच अंतर करने का कोई तरीका नहीं है।
प्रश्न 1) क्या इस के आसपास काम करने का कोई मानक तरीका है?
एक और नुकसान है कि, मैं प्रवेश बिंदु पर अनुरोध को मान्य करने के @Valid एनोटेशन उपयोग नहीं कर सकते है - coz यह केवल एक आंशिक है। इसलिए, अमान्य डेटा सिस्टम में हो सकता है।
उदाहरण के लिए, कल्पना वहाँ निम्नलिखित परिभाषा के साथ अतिरिक्त क्षेत्र था:
@Min(0)
@Max(100)
private Integer lengthOfResidencyInYears,
और उपयोगकर्ता गलती से 190 लिखा जाता है (जब वे वास्तव में 19 साल के लिए होती है), यह असफल नहीं होता।
PATCH के बजाय, अगर मैं PUT का इस्तेमाल किया था, ग्राहक पूरा पता वस्तु भेजने के लिए की आवश्यकता होगी। यह लाभ है कि मैं @Valid का उपयोग सुनिश्चित करने के लिए कि पता वास्तव में वैध
है एक आधार है कि किसी GET हमेशा किया जाना चाहिए, क्यों होगा डाल एक का उपयोग नहीं अपडेट करने से पहले करता है सकते हैं पैच पर? क्या मुझे कुछ याद आ रही है?
एक तरफ
मेरा निष्कर्ष है कि गतिशील रूप से टाइप किया भाषाओं का उपयोग डेवलपर्स PATCH का उपयोग कर के रूप में मैं किसी भी लाभ से एक स्थिर टाइप किया भाषा लाइन जावा या सी # में प्रयोग करने के लिए नहीं देख सकते हैं के समर्थकों हो रहा है। यह बस अधिक जटिलता जोड़ने लगता है।
स्थिति मान्य लगता है, पैच अनुरोध के बाद आपकी डीबी क्वेरी लाइन दिखानी चाहिए: "वैकल्पिक पता पंक्ति 2", चूंकि आप जांच रहे हैं, partialAddress.getLine2()! = Null। – kuhajeyan
एक पैच-अनुरोध में क्लाइंट द्वारा गणना की गई निर्देश होनी चाहिए, सर्वर कुछ संसाधनों के राज्य ए को राज्य बी में बदलने के लिए उपयोग कर सकता है और न केवल एक सरल आंशिक अद्यतन है। आगे पढ़ने: [एसओ दस्तावेज] (http://stackoverflow.com/documentation/http/3423/http-for-apis/11812/edit-a-resource#t=201610031245323472567) और [अच्छा ब्लॉग पोस्ट] (http://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/) –
यह एक अच्छा सवाल है। लाइन 2 में शून्य के बारे में ठीक है क्योंकि आप मैन्युअल रूप से फ़ील्ड को मैप करते हैं और आप ओवरराइट करने के लिए गैर शून्य मानों की जांच करते हैं। वर्तमान में मैं एक प्रोजेक्ट पर काम कर रहा हूं जहां हम [डोज़र] (http://dozer.sourceforge.net/documentation/usage.html) का उपयोग करते हैं और आप नल को मैप करना चुन सकते हैं। वैसे भी हम संसाधनों को जोड़ने/बनाने और उन्हें संशोधित करने के लिए POST का उपयोग करते हैं, हालांकि इस मैपर के साथ यह आंशिक मैपिंग कर सकता है। तो अगर मैं पसंदीदा तरीका है या मुझे POST (create), PUT (पूर्ण अपडेट), पैच (आंशिक अपडेट) का उपयोग करना चाहिए तो बहस कर रहा हूं। –