DELETE ควรจะเป็น idempotent
หากฉันลบhttp://example.com/account/123จะเป็นการลบบัญชี
ถ้าฉันทำอีกฉันจะคาดหวัง 404 เนื่องจากบัญชีไม่มีอยู่อีกต่อไป? ถ้าฉันพยายามลบบัญชีที่ไม่เคยมีอยู่จะทำอย่างไร
DELETE ควรจะเป็น idempotent
หากฉันลบhttp://example.com/account/123จะเป็นการลบบัญชี
ถ้าฉันทำอีกฉันจะคาดหวัง 404 เนื่องจากบัญชีไม่มีอยู่อีกต่อไป? ถ้าฉันพยายามลบบัญชีที่ไม่เคยมีอยู่จะทำอย่างไร
คำตอบ:
ในทุกกรณี (นอกเหนือจากปัญหาข้อผิดพลาด - ดูด้านล่าง) บัญชีไม่มีอยู่อีกต่อไป
จากที่นี่
"เมธอดยังสามารถมีคุณสมบัติของ" idempotence "ในนั้น ( นอกเหนือจากข้อผิดพลาดหรือปัญหาการหมดอายุ ) ผลข้างเคียงของ N> 0 คำร้องขอเหมือนกันเหมือนกับการร้องขอครั้งเดียววิธีแบ่งปัน GET, HEAD, PUT และ DELETE คุณสมบัตินี้นอกจากนี้วิธีการตัวเลือกและการติดตามไม่ควรมีผลข้างเคียงและดังนั้นจึงเป็น idempotent โดยเนื้อแท้ "
บิตที่สำคัญมีผลข้างเคียงของคำขอที่เหมือนกันของ N> 0 จะเหมือนกับในคำขอเดี่ยว
คุณจะถูกต้องเพื่อคาดหวังว่ารหัสสถานะจะแตกต่างกัน แต่สิ่งนี้จะไม่ส่งผลกระทบต่อแนวคิดหลักของ idempotency - คุณสามารถส่งคำขอได้มากกว่าหนึ่งครั้งโดยไม่มีการเปลี่ยนแปลงเพิ่มเติมในสถานะของเซิร์ฟเวอร์
Idempotentเป็นเรื่องเกี่ยวกับผลกระทบของการร้องขอไม่ใช่เกี่ยวกับรหัสการตอบสนองที่คุณได้รับ
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2พูดว่า:
เมธอดยังสามารถมีคุณสมบัติของ "idempotence" ในนั้น (นอกเหนือจากข้อผิดพลาดหรือปัญหาการหมดอายุ) ผลข้างเคียงของ N> 0 คำขอที่เหมือนกันจะเหมือนกันสำหรับคำขอเดียว
ในขณะที่คุณอาจได้รับรหัสการตอบสนองที่แตกต่างกันผลของการส่งคำขอ N + 1 DELETE ไปยังทรัพยากรเดียวกันก็ถือได้ว่าเหมือนกัน
ความแตกต่างที่สำคัญคือ idempotent หมายถึงผลข้างเคียงที่ไม่ทั้งหมด -effects หรือการตอบสนอง หากคุณทำเช่นDELETE http://example.com/account/123
นั้นเอฟเฟกต์คือบัญชี 123 จะถูกลบออกจากเซิร์ฟเวอร์ นั่นคือเอฟเฟกต์หนึ่งเดียวเท่านั้นการเปลี่ยนแปลงเพียงครั้งเดียวจะเปลี่ยนเป็นสถานะของเซิร์ฟเวอร์ ตอนนี้สมมติว่าคุณทำDELETE http://example.com/account/123
คำขอเดียวกันอีกครั้งเซิร์ฟเวอร์จะตอบกลับต่างกัน แต่สถานะของมันจะเหมือนกัน
มันไม่เหมือนคำขอ DELETE ตัดสินใจที่จะเปลี่ยนสถานะเซิร์ฟเวอร์ในวิธีที่ต่างกันเนื่องจากบัญชีหายไปเช่นการลบบัญชีอื่นหรือออกจากบันทึกข้อผิดพลาด ไม่คุณสามารถโทรขอลบเดียวกันได้ล้านครั้งและคุณสามารถมั่นใจได้ว่าเซิร์ฟเวอร์อยู่ในสถานะเดียวกับครั้งแรกที่คุณโทรมา
จากHTTP RFC :
เมธอดยังสามารถมีคุณสมบัติของ "idempotence" ในนั้น (นอกเหนือจากข้อผิดพลาดหรือปัญหาการหมดอายุ) ผลข้างเคียงของ N> 0 คำขอที่เหมือนกันจะเหมือนกันสำหรับคำขอเดียว
โปรดทราบว่า "ผลข้างเคียง" ไม่ใช่ "การตอบสนอง"
ใช่. โดยไม่คำนึงถึงรหัสการตอบสนอง
จากRFC ล่าสุดสำหรับ HTTP 1.1 (เหมืองที่เน้น):
เมธอด Idempotent แตกต่างเพราะคำขอสามารถทำซ้ำได้โดยอัตโนมัติหากความล้มเหลวในการสื่อสารเกิดขึ้นก่อนที่ลูกค้าจะสามารถอ่านการตอบสนองของเซิร์ฟเวอร์ ตัวอย่างเช่นหากลูกค้าส่งคำขอ PUT และการเชื่อมต่อพื้นฐานถูกปิดก่อนที่จะได้รับการตอบสนองใด ๆ ลูกค้าสามารถสร้างการเชื่อมต่อใหม่และลองคำขอ idempotent อีกครั้ง มันรู้ว่าการทำซ้ำการร้องขอจะมีผลเหมือนกันแม้ว่าคำขอเดิมจะสำเร็จแม้ว่าการตอบกลับอาจแตกต่างกัน
มันบอกอย่างชัดเจนว่าการตอบสนองอาจแตกต่างกัน ที่สำคัญกว่านั้นคือมันแสดงให้เห็นถึงเหตุผลของแนวคิด: หากการกระทำนั้นเป็น idempotent ลูกค้าสามารถทำซ้ำการกระทำได้เมื่อพบข้อผิดพลาดและรู้ว่าจะไม่เกิดปัญหาใด ๆ จากการทำเช่นนั้น ถ้าไม่ลูกค้าจะต้องทำแบบสอบถามเพิ่มเติม (อาจGET
) เพื่อดูว่าก่อนหน้านี้มีประสิทธิภาพก่อนที่จะทำซ้ำการกระทำที่ปลอดภัย ตราบใดที่เซิร์ฟเวอร์สามารถรับประกันได้การกระทำก็คือ idempotent อ้างอิงจากความคิดเห็นอื่น :
การคำนวณ idempotenceนั้นเกี่ยวกับความทนทานของระบบ เนื่องจากสิ่งต่าง ๆ สามารถล้มเหลว (เช่นเครือข่ายดับ), เมื่อตรวจพบความล้มเหลวคุณจะกู้คืนได้อย่างไร? การกู้คืนที่ง่ายที่สุดคือการทำมันอีกครั้ง แต่วิธีนี้ใช้ได้ผลถ้าทำอีกครั้งคือ idempotent เช่น
discard(x)
idempotent แต่pop()
ไม่ใช่ มันคือทั้งหมดที่เกี่ยวกับการกู้คืนข้อผิดพลาด
อ้างจากคำตอบอื่นของฉันที่นี่ :
ในอดีต RFC 2616 ซึ่งตีพิมพ์เมื่อปี 1999 เป็นรายละเอียด HTTP 1.1 ที่มีการอ้างอิงมากที่สุด น่าเสียดายที่คำอธิบายเกี่ยวกับ idempotency นั้นคลุมเครือซึ่งทำให้พื้นที่สำหรับการอภิปรายทั้งหมดนี้ แต่รายละเอียดดังกล่าวถูกแทนที่โดย RFC 7231 ยกมาจากRFC 7231 ส่วน 4.2.2 วิธี Idempotentเน้นการทำเหมือง:
วิธีการร้องขอนั้นถูกพิจารณาว่าเป็น "idempotent" หากผลที่ตั้งใจไว้บนเซิร์ฟเวอร์ของคำขอที่เหมือนกันหลาย ๆ ครั้งที่ใช้วิธีการนั้นเป็นแบบเดียวกันกับเอฟเฟกต์สำหรับคำขอดังกล่าวเพียงครั้งเดียว วิธีการคำขอที่กำหนดโดยข้อกำหนดนี้, PUT, DELETEและวิธีการร้องขอความปลอดภัย เป็น idempotent
ดังนั้นมันถูกเขียนในรายละเอียด idempotency คือทั้งหมดที่เกี่ยวกับผลกระทบบนเซิร์ฟเวอร์ DELETE ตัวแรกส่งคืน 204 และจากนั้น DELETE ที่ส่งคืน 404 ที่ตามมารหัสสถานะที่แตกต่างนั้นไม่ได้ทำให้ DELETE ไม่ใช่ idempotent การใช้อาร์กิวเมนต์นี้เพื่อพิสูจน์ว่ามีการส่งคืน 204 ครั้งถัดไปนั้นไม่เกี่ยวข้องเลย
ตกลงดังนั้นมันไม่เกี่ยวกับ idempotency แต่คำถามติดตามอาจเกิดอะไรขึ้นถ้าเรายังคงเลือกใช้ 204 ในการลบครั้งต่อไป ตกลงหรือไม่
คำถามที่ดี. แรงจูงใจสามารถเข้าใจได้: เพื่อให้ลูกค้ายังคงบรรลุผลตามที่ตั้งใจไว้โดยไม่ต้องกังวลเกี่ยวกับการจัดการข้อผิดพลาด ฉันจะบอกว่าการคืน 204 ใน DELETE ต่อมานั้นเป็น "white lie" ฝั่งเซิร์ฟเวอร์ที่ไม่เป็นอันตรายซึ่งฝั่งไคลเอ็นต์จะไม่บอกความแตกต่างทันที นั่นเป็นสาเหตุที่มีคนทำแบบนั้นอยู่ในป่าและมันยังใช้ได้อยู่ เพียงจำไว้ว่าการโกหกดังกล่าวถือได้ว่าเป็นความหมายที่แปลกเพราะ "GET / ไม่มีอยู่" ส่งคืน 404 แต่ "DELETE / ไม่มีอยู่" ให้ 204, ณ จุดนั้นลูกค้าจะเข้าใจว่าบริการของคุณไม่สอดคล้องกับส่วน 6.5.4 404 ไม่พบ
แต่วิธีที่ตั้งใจไว้โดย RFC 7231 เช่นการคืน 404 ในการลบครั้งต่อไปไม่น่าจะเป็นปัญหาตั้งแต่แรก นักพัฒนาหลายคนเลือกที่จะทำเช่นนั้น นั่นอาจเป็นเพราะลูกค้าที่ใช้ HTTP DELETE (หรือวิธีการ HTTP ใด ๆ สำหรับเรื่องนั้น) จะไม่คิดว่าผลลัพธ์นั้นจะประสบความสำเร็จ 2xx เสมอ จากนั้นเมื่อนักพัฒนาเริ่มพิจารณาการจัดการข้อผิดพลาด 404 ไม่พบจะเป็นหนึ่งในข้อผิดพลาดแรกที่เข้ามาในใจ ณ จุดนั้นเขา / เธอหวังว่าจะได้ข้อสรุปว่าปลอดภัยสำหรับการดำเนินการ HTTP DELETE เพื่อละเว้นข้อผิดพลาด 404 แก้ไขปัญหา.
ฉันคิดเหมือนกัน 404 - บัญชีไม่มีอยู่
คุณสามารถโต้แย้ง 400 - คำขอไม่ถูกต้อง แต่ในแง่ของ REST วัตถุที่คุณขอให้ดำเนินการจะไม่ปรากฏขึ้น นั่นแปลเป็น 404