ควรการดำเนินการ 'วาง' สงบกลับคืนบางสิ่ง


437

ฉันสงสัยว่าความคิดเห็นของผู้คนเป็นอย่างไรเมื่อมีการPUTดำเนินการที่สงบซึ่งไม่ได้ผลตอบแทนใด ๆ ในการตอบสนอง

คำตอบ:


615

ข้อมูลจำเพาะ HTTP ( RFC 2616 ) มีคำแนะนำจำนวนมากที่สามารถใช้ได้ นี่คือการตีความของฉัน:

  • รหัสสถานะ HTTP 200 OKสำหรับ PUT ที่สำเร็จของการอัพเดตเป็นทรัพยากรที่มีอยู่ ไม่ต้องมีการตอบสนองใด ๆ (ต่อมาตรา 9.6 , 204 No Contentแม้จะเหมาะสมกว่า.)
  • รหัสสถานะ HTTP 201 Createdสำหรับ PUT ที่ประสบความสำเร็จของทรัพยากรใหม่โดยเฉพาะ URI ที่เฉพาะเจาะจงที่สุดสำหรับทรัพยากรใหม่ที่ส่งคืนในฟิลด์ส่วนหัวสถานที่ตั้งและ URI อื่น ๆ ที่เกี่ยวข้องและข้อมูลเมตาของทรัพยากรที่สะท้อนในเนื้อหาการตอบสนอง ( RFC 2616 มาตรา 10.2.2 )
  • รหัสสถานะ HTTP 409 Conflictสำหรับใส่ที่ไม่ประสบความสำเร็จเนื่องจากมี 3 ปรับเปลี่ยนของบุคคลที่มีรายชื่อของความแตกต่างระหว่างการปรับปรุงความพยายามและทรัพยากรในปัจจุบันในร่างกายตอบสนองได้ ( RFC 2616 มาตรา 10.4.10 )
  • รหัสสถานะ HTTP 400 Bad Requestสำหรับ PUT ที่ไม่สำเร็จพร้อมข้อความภาษาธรรมชาติ (เช่นอังกฤษ) ในเนื้อความการตอบสนองที่อธิบายสาเหตุที่ PUT ล้มเหลว ( RFC 2616 มาตรา 10.4 )

25
@stian ที่น่าสนใจ! ดูเหมือนว่าค่อนข้างน่าเกรงขามในส่วนของ Mozilla เนื่องจากฉันไม่พบสิ่งใดใน RFC 2616 (ส่วนที่สะดุดตา10.2 สำเร็จ 2xxและ10.2.1 200 OK ) ที่ออกกฎการใช้200PUT, DELETE หรือวิธีอื่นใดโดยเฉพาะ ฉันพลาดอะไรไปหรือเปล่า? เช่น Mozilla กลายเป็นหัวหน้าของ W3 และ IETF หรือไม่ ;) หรือบางทีพวกเขาไม่เคยได้ยินเกี่ยวกับหลักการความทนทานของ Postel
ระบบหยุดชั่วคราว

52
@stian: ประโยคนั้นถูกลบออกเมื่อวันที่ 3 กุมภาพันธ์ 2013 อาจเป็นเพราะมีคนอ่านที่นี่ ;) developer.mozilla.org/en-US/docs/HTTP/…
Christian Strempfer

6
ความหมายของวิธีการ PUT คือการเพิกเฉยไม่ว่าสถานะปัจจุบันของทรัพยากรจะเป็นเช่นไรดังนั้นเพื่อส่งคืนข้อขัดแย้ง 409 สำหรับ PUT ที่ไม่สำเร็จเนื่องจากการแก้ไขโดยบุคคลที่สามจะสมเหตุสมผลถ้าคำขอนั้นมีเงื่อนไข
Pedro Werneck

8
@systemPAUSE คำตอบที่ดี จุดเล็ก ๆ จุดหนึ่ง: ถ้าคุณจะไม่กลับไปตอบสนองร่างกายเพื่อการดำเนินงานที่ประสบความสำเร็จฉันขอแนะนำให้ใช้ 204 โดยเฉพาะ ลูกค้าบางราย (ตัวอย่างเช่น jQuery Ajax) จะทำให้หายใจไม่ออกหากพวกเขาต้องการการตอบสนองความยาวที่ไม่เป็นศูนย์ แต่ไม่ได้รับ คุณสามารถดูตัวอย่างนี้ในคำถามนี้
nick_w

3
อาจมีการอัปเดต RFC2616 ตั้งแต่ตอบคำถามนี้ ไม่มีที่กล่าวถึงNo response body neededในข้อที่ 9.6 เมื่อเทียบกับ 200 ในความเป็นจริงหน่วยการตอบสนองไม่ได้กล่าวถึง PUT เพียงระบุIf an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request.
james

164

ตรงข้ามกับคำตอบส่วนใหญ่ที่นี่ฉันคิดว่า PUT ควรส่งคืนทรัพยากรที่อัปเดต (นอกเหนือจากรหัส HTTP ของหลักสูตร)

สาเหตุที่คุณต้องการส่งคืนทรัพยากรเนื่องจากการตอบสนองสำหรับการดำเนินการ PUT เนื่องจากเมื่อคุณส่งการแสดงทรัพยากรไปยังเซิร์ฟเวอร์เซิร์ฟเวอร์ยังสามารถใช้การประมวลผลบางอย่างกับทรัพยากรนี้ได้ดังนั้นลูกค้าต้องการทราบว่าทรัพยากรนี้ทำอย่างไร ดูหลังจากคำขอเสร็จสมบูรณ์ (ไม่เช่นนั้นจะต้องออกคำขอ GET อื่น)


3
"เซิร์ฟเวอร์ยังสามารถใช้การประมวลผลบางอย่างกับทรัพยากรนี้": ฉันใหม่สิ่งนี้ มันสงบแล้วจริงเหรอ?
Raedwald

22
@ Raedwald แน่ใจว่ามันเป็น REST ไม่ต้องการให้มีการอัปเดตทรัพยากรทั้งหมดใน PUT แม้ว่าจะแนะนำโดยทั่วไปก็ตาม บางฟิลด์อาจไม่เหมาะสมที่จะอัปเดต - วันที่สร้างหรือวันที่แก้ไขล่าสุดเช่นไม่ควรรวมอยู่ในเนื้อหาของ PUT แต่น่าจะเปลี่ยนไปเนื่องจาก PUT ที่ได้รับการกล่าวว่าฉันไม่เห็นด้วยกับ LiorH ว่า PUT ควรส่งคืนทรัพยากร; ฉันต้องการ GET หลังจาก PUT เพื่อรับทรัพยากรที่อัปเดต
Randolpho

19
@Randolpho REST ไม่ต้องการให้ทรัพยากรทั้งหมดได้รับการอัพเดตบน PUTไม่ควรเป็นกรณีของ PATCH หรือไม่?
Marco Ciambrone

14
@MarcoCiambrone ใช่ฉันเห็นด้วยและฉันอ่านความคิดเห็นก่อนหน้าของฉัน ฉันได้เปลี่ยนเพลงใน REST และ PUT - PUT ควรเป็น idempotent เสมอและไม่ควรใช้สำหรับการอัพเดทบางส่วน POST เป็นทางเลือกเดียวเว้นแต่จะรองรับ PATCH ซึ่งในกรณีนี้ PATCH อาจเป็นทางเลือกที่ดี อย่างไรก็ตาม PATCH นั้นเป็นกริยาใหม่และอาจไม่รองรับกรอบงานฝั่งเซิร์ฟเวอร์บางตัว
Randolpho

2
คำตอบนั้นเขียนได้ดีก่อน rfc7231 แต่ส่วนที่ 4.3.4ทำให้ชัดเจน "วิธี PUT ร้องขอให้สร้างหรือแทนที่สถานะของทรัพยากรเป้าหมายด้วยสถานะที่กำหนดโดยการแสดงที่อยู่ในเพย์โหลดคำขอข้อความ"
aaaaaa

3

ฉันคิดว่าเป็นไปได้ที่เซิร์ฟเวอร์จะส่งคืนเนื้อหาตามการตอบกลับ PUT หากคุณใช้รูปแบบห่อหุ้มการตอบสนองที่ช่วยให้ข้อมูลไซด์โหลด (เช่นรูปแบบที่ใช้โดยข้อมูล ember) จากนั้นคุณสามารถรวมวัตถุอื่น ๆ ที่อาจได้รับการแก้ไขผ่านทริกเกอร์ฐานข้อมูล ฯลฯ (ข้อมูล Sideloaded จะลดลงอย่างชัดเจน # คำขอและนี่เป็นสถานที่ที่เหมาะสำหรับการเพิ่มประสิทธิภาพ)

ถ้าฉันยอมรับ PUT และไม่มีอะไรจะรายงานกลับฉันใช้รหัสสถานะ 204 โดยไม่มีเนื้อหา หากฉันมีสิ่งที่ต้องรายงานฉันใช้รหัสสถานะ 200 และรวมเนื้อหา


2

HTTP / 1.1 สเปค (มาตรา 9.6) กล่าวถึงรหัสที่เหมาะสมตอบสนอง / ข้อผิดพลาด อย่างไรก็ตามมันไม่ได้อยู่ที่เนื้อหาการตอบสนอง

คุณคาดหวังอะไร รหัสตอบกลับ HTTP แบบง่าย (200 เป็นต้น) ดูเหมือนจะตรงไปตรงมาและชัดเจนสำหรับฉัน


ใช่ แต่ถ้าคุณต้องการตรวจสอบว่าข้อมูลที่แทรกลงใน db หลังจาก PUT หรือ POST แสดงข้อมูลจริงที่คุณต้องการจริงๆ มันจะดีกว่าถ้า HTTP สามารถส่งเนื้อความของการตอบกลับกลับมาได้
tnkh

1
@tnkh สิ่งที่คุณแนะนำคือจริงจังเป็นความคิดที่น่ากลัว โทรออก GET แยกกันหลังจากอัปเดตสำเร็จเพื่อให้ได้ตามที่คุณต้องการ เพื่อให้มั่นใจในประสิทธิภาพแนะนำเลเยอร์แคชหากคุณประสบปัญหาในแผนกนี้ เราไม่สามารถแก้ปัญหาเหล่านี้ได้ด้วยการทำสิ่งที่ไม่เหมาะสมด้วยตรรกะ อย่ายุ่งกับหลักการเขียนโปรแกรมที่ 'แข็ง' และพื้นฐานซึ่งควรเป็นเรื่องสามัญในปี 2020 มันเป็นความอัปยศ!
XDS

@XDS ฉันรับทราบส่วนแรกของความคิดเห็น แต่ไม่สามารถกลอกตาของฉันหลังจากนั้น ความคิดเห็นเฮฮา
tnkh

ขอบคุณที่ให้รายละเอียดว่าทำไมคุณถึงคิดว่าเฮฮา
XDS

2

หากแบ็คเอนด์ของ REST API เป็นฐานข้อมูลเชิงสัมพันธ์ของ SQL ดังนั้น

  1. คุณควรมีRowVersionในทุก ๆ ระเบียนที่สามารถปรับปรุงได้ (เพื่อหลีกเลี่ยงปัญหาการอัพเดทที่หายไป )
  2. คุณควรส่งคืนสำเนาของบันทึกใหม่หลังจาก PUT (เพื่อรับRowVersionใหม่)

หากคุณไม่สนใจเกี่ยวกับการอัปเดตที่สูญหายหรือหากคุณต้องการบังคับให้ลูกค้าทำ GET ทันทีหลังจากใส่แล้วอย่าส่งคืนอะไรจาก PUT


1

รหัสตอบกลับ HTTP 201 สำหรับ "สร้าง" พร้อมกับส่วนหัว "สถานที่ตั้ง" เพื่อชี้ไปที่ที่ลูกค้าสามารถค้นหาทรัพยากรที่สร้างขึ้นใหม่


5
วัตถุ PUT ไม่ได้ (หรือไม่ควร) ทรัพยากรที่สร้างขึ้นใหม่
kdazzle

9
@kdazzle PUT สามารถเป็นทรัพยากรที่สร้างขึ้นใหม่ได้อย่างแน่นอนและมักจะเป็น w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
Charlie Schliesser

3
เพียงเพื่ออธิบายความคิดเห็นของฉันดีขึ้นเล็กน้อย ใส่หมายถึงวางรายการนี้ที่ตำแหน่งเฉพาะนี้แทนที่สิ่งที่มีอยู่ในปัจจุบัน (ถ้ามี)
user1751825

3
ใช่ "การแทนที่สิ่งที่มีอยู่ในปัจจุบัน" เป็นวลีสำคัญ ควรมีอยู่แล้วและจะถูกแทนที่ PUT ไม่ควรสร้างทรัพยากรใหม่
Kevin M

3
@KevinM เช่นเดียวกับRFC doc rfc7231ล่าสุดกล่าวว่าสามารถสร้างทรัพยากรได้: "วิธี PUT ร้องขอให้สถานะของทรัพยากรเป้าหมายถูก สร้างหรือแทนที่ [... ]" และเหตุผลที่คุณคิดว่า PUT ไม่สามารถสร้างได้ ทรัพยากรใหม่เป็นเพราะคุณไม่จำเป็นต้องทราบตำแหน่งของทรัพยากรใหม่ แต่ถ้าคุณรู้ตำแหน่ง / ตัวระบุมันสามารถสร้างได้หากยังไม่มี
Leo Lei

0

ฉันใช้ RESTful API ในบริการของฉันและนี่คือความเห็นของฉัน: ก่อนอื่นเราต้องไปที่มุมมองทั่วไป:PUTใช้เพื่ออัปเดตทรัพยากรที่ไม่ได้สร้างหรือรับ

ฉันกำหนดทรัพยากรด้วย: Stateless resourceและStateful resource:

  • ทรัพยากรไร้สัญชาติสำหรับทรัพยากรเหล่านี้เพียงแค่ส่งคืน HttpCode ด้วยเนื้อหาที่ว่างเปล่าก็เพียงพอแล้ว

  • ทรัพยากรที่เป็นของรัฐตัวอย่างเช่น: เวอร์ชันของทรัพยากร สำหรับทรัพยากรประเภทนี้คุณต้องระบุเวอร์ชันเมื่อคุณต้องการเปลี่ยนดังนั้นให้ส่งคืนทรัพยากรทั้งหมดหรือส่งคืนเวอร์ชันให้กับลูกค้าดังนั้นลูกค้าไม่จำเป็นต้องส่งคำขอรับหลังจากการดำเนินการอัพเดท

แต่สำหรับบริการหรือระบบให้มันsimple,clearly,easy to use and maintainเป็นสิ่งที่สำคัญที่สุด


6
"PUT ใช้เพื่ออัปเดตทรัพยากรที่ไม่ได้สร้างหรือรับ" - นั่นไม่จริงหรือไม่ใช่เรื่องธรรมดา ตามข้อมูลจำเพาะ PUT สามารถสร้างทรัพยากร Clear = ตามสเป็คที่รู้จักกันทั่วไป
Imre Pühvel

-3

เช่นเดียวกับเนื้อความคำร้องขอที่ว่างเปล่านั้นยังคงรักษาวัตถุประสงค์เดิมของคำขอ GET และเนื้อหาการตอบสนองที่ว่างเปล่านั้นก็ยังคงวัตถุประสงค์เดิมของคำขอ PUT


-3

ดูเหมือนจะโอเค ... แม้ว่าฉันจะคิดว่าตัวบ่งชี้พื้นฐานของความสำเร็จ / ล้มเหลว / เวลาโพสต์ / # ไบต์ที่ได้รับ / ฯลฯ น่าจะดีกว่า

แก้ไข: ฉันกำลังคิดตามบรรทัดของความถูกต้องของข้อมูลและ / หรือการเก็บบันทึก ข้อมูลเมตาเช่นแฮช MD5 หรือการประทับเวลาสำหรับเวลาที่ได้รับอาจมีประโยชน์สำหรับดาต้าไทล์ขนาดใหญ่


1
วิธีการประมาณ 200 ตกลงในหัวข้อการตอบสนองสถานะ? คิดว่าเพียงพอที่จะพูดว่า "ทำงานได้ดีขอบคุณ?"
AnthonyWJones

ส่วนหัวของการตอบสนองจะมีรหัสสถานะและใช่เรากำลังพูดถึง HTTP ที่จุดนี้ :)
AwkwardCoder

-4

เป็นการดีที่มันจะกลับมาตอบสนองความสำเร็จ / ล้มเหลว


13
ไม่ได้อยู่ในร่างกายของการตอบสนองแม้ว่า รหัสสถานะ HTTP เป็นที่สำหรับการทำเช่นนั้น บางทีถ้ามีข้อผิดพลาดบางข้อมูลข้อผิดพลาดที่อาจจะกลับมาใน bidy การตอบสนอง
เทพพอล

-4

มีความแตกต่างระหว่างส่วนหัวและเนื้อหาของการตอบกลับ HTTP PUT ไม่ควรส่งคืนเนื้อความ แต่ต้องส่งคืนรหัสตอบกลับในส่วนหัว เพียงเลือก 200 ถ้าประสบความสำเร็จและ 4xx ถ้าไม่ใช่ ไม่มีสิ่งนั้นเป็นรหัสส่งคืน null ทำไมคุณถึงต้องการทำเช่นนี้?

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.