การปฏิบัติที่ดีที่สุดสำหรับการตอบสนอง POST ที่สงบ


217

ดังนั้นจึงไม่มีอะไรใหม่ที่นี่ฉันแค่พยายามที่จะได้รับการชี้แจงและดูเหมือนจะไม่พบในโพสต์อื่น ๆ

ฉันกำลังสร้างทรัพยากรใหม่อย่างสงบพูด:

/books (POST)

กับร่างกาย:

{
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

ฉันรู้ว่าฉันควรส่งคืน 201 (สร้าง) ด้วยส่วนหัว Location ของทรัพยากรใหม่:

Location: /books/12345

คำถามที่ฉันไม่สามารถตอบได้ก็คือสิ่งที่เซิร์ฟเวอร์ควรส่งคืนในร่างกาย

ฉันได้ตอบกลับประเภทนี้บ่อยครั้ง:

{
  id: 12345,
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

ฉันได้ทำสิ่งนี้ด้วยเหตุผลสองสามประการ:

  1. ฉันได้เขียน API สำหรับเฟรมเวิร์กเอนด์เช่น angularjs ในกรณีของฉันโดยเฉพาะฉันใช้ทรัพยากรเชิงมุมและฉันมักจะต้องการเพียงแค่รหัสสำหรับทรัพยากรเพื่อค้นหามัน หากฉันไม่ได้ส่งคืนรหัสในส่วนการตอบกลับฉันจะต้องแยกวิเคราะห์ออกจากส่วนหัว Location
  2. ใน GET ของหนังสือทั้งหมดฉันมักจะคืนค่าวัตถุทั้งหมดไม่ใช่แค่ id ในกรณีนี้รหัสลูกค้าของฉันไม่จำเป็นต้องแยกความแตกต่างว่าจะรับ ID จากที่ใด (ส่วนหัวสถานที่ตั้งหรือเนื้อหา)

ตอนนี้ฉันรู้ว่าฉันอยู่ในพื้นที่สีเทาที่นี่จริง ๆ แต่คนส่วนใหญ่บอกว่าการคืนทรัพยากรทั้งหมดเป็นการปฏิบัติที่ไม่ดี แต่ถ้าเซิร์ฟเวอร์มีการเปลี่ยนแปลง / เพิ่มข้อมูลให้กับทรัพยากร มันเพิ่มรหัสแน่นอน แต่อาจเพิ่มสิ่งอื่น ๆ เช่นการประทับเวลา ในกรณีที่ฉันไม่ส่งคืนทรัพยากรทั้งหมดจะเป็นการดีกว่าที่จะทำ POST ส่งคืน id จากนั้นให้ไคลเอนต์ดำเนินการ GET เพื่อรับทรัพยากรใหม่


ฉันชอบร่างกายที่ว่างเปล่าสำหรับการตอบกลับ POST ไม่ควรค่าส่วนหัว RESTful Location เป็น URI (ตัวระบุทรัพยากรที่ไม่ซ้ำ) ดังนั้นคุณควรใช้มันเป็น ID และไม่แยกวิเคราะห์เพื่อหา ID ภายในของเซิร์ฟเวอร์ IMO ผู้ใช้ RESTful API ควรนำทางโดยใช้ไฮเปอร์ลิงก์ที่จัดเตรียมไว้และไม่สร้างพา ธ โดยคาดเดาว่าเซิร์ฟเวอร์ใดหาตำแหน่งที่ตั้งของทรัพยากร ... และหลังจากนี้ลูกค้าไม่ทราบสถานะของทรัพยากรที่เพิ่งสร้างมาใช่หรือไม่ การทำซ้ำมันทำให้สิ้นเปลืองทรัพยากรเครือข่าย
ch4mp

1
สำหรับการสร้าง / แทรกสถานะ 201 - สร้างที่ตั้งส่วนหัว→ localhost: 8080 / พนักงาน / 1 (ดู: ที่นี่ )
Hassan Tareq

คำตอบ:


129

การส่งคืนออบเจ็กต์ทั้งหมดในการอัปเดตดูเหมือนจะไม่เกี่ยวข้องกันมาก แต่ฉันแทบจะไม่เห็นว่าทำไมการส่งคืนออบเจ็กต์ทั้งหมดเมื่อมีการสร้างจะเป็นวิธีปฏิบัติที่ไม่ดีในกรณีใช้งานปกติ สิ่งนี้จะเป็นประโยชน์อย่างน้อยในการรับ ID ได้ง่ายและเพื่อให้ได้เวลาที่เกี่ยวข้อง นี่คือพฤติกรรมเริ่มต้นที่เกิดขึ้นจริงเมื่อนั่งร้านด้วย Rails

ฉันไม่เห็นประโยชน์ใด ๆ ในการส่งคืนเฉพาะ ID และดำเนินการตามคำขอ GET เพื่อรับข้อมูลที่คุณสามารถได้รับจาก POST เริ่มต้นของคุณ

อย่างไรก็ตามตราบใดที่ API ของคุณสอดคล้องกันฉันคิดว่าคุณควรเลือกรูปแบบที่เหมาะกับความต้องการของคุณที่สุด ไม่มีวิธีที่ถูกต้องในการสร้าง REST API, imo


26
ฉันรู้ว่านี่เก่า แต่ฉันสามารถโต้แย้งที่น่าเชื่อถือได้สำหรับการใช้ GET หลัง POST ของคุณ ในข้อมูลจำเพาะ http / 1.1 เครื่องมือประวัติใด ๆ สามารถเพิกเฉยต่อการตั้งค่าแคชที่ส่งคืนจากการตอบกลับของ GET ของคุณ ... ดังนั้นหากผู้ใช้ของคุณใช้ปุ่มย้อนกลับในเบราว์เซอร์เพื่อกลับไปที่หน้านี้หลังจากที่คุณอัปเดตด้วย POST ข้อมูลที่แคชจาก GET ดั้งเดิม ดังนั้นหากคุณนำ GET มาใช้ใหม่คุณสามารถอัปเดตแคชและรับภาพรวมที่ดีกว่าว่าหน้าเว็บจะดูอย่างไรเมื่อพวกเขาออกไป ...
Shaded

8
@Shaded หาก API ได้รับการออกแบบมาให้ใช้งานโดยแอพแสดงว่าอาร์กิวเมนต์ของคุณสำหรับการร้องขอสองรายการไม่ได้เก็บไว้ ที่นั่นคุณมักจะแคชข้อมูลโดยเก็บวัตถุประเภทรุ่นไว้ในหน่วยความจำซึ่งโดยทั่วไปแล้วจะตอบกลับคำขอ POST และเกี่ยวกับเบราว์เซอร์การตอบสนองต่อคำขอ POST ไม่ได้ทำให้เจ็บปวดจริงๆตราบใดที่ยังมีจุดสิ้นสุด GET api
Jeehut

ฉันสมัครสมาชิกสิ่งที่แดเนียลระบุที่นี่ แม้ว่าคุณจะตรวจสอบเฟรมเวิร์กที่เป็นผู้ใหญ่อย่าง Spring Data พวกมันก็จะส่งคืนออบเจ็กต์ทั้งหมดเสมอหลังจากยังคงอยู่ ฉันคิดว่ามันเป็นวิธีปฏิบัติที่ดีเช่นเดียวกับในไคลเอนต์ของคุณคุณจะบันทึกเซิร์ฟเวอร์ไปกลับเพื่อให้ได้ข้อมูลเดียวกัน
frandevel

205

การส่งคืนวัตถุใหม่นั้นเหมาะสมกับหลักการ REST ของ "Uniform Interface - การจัดการทรัพยากรผ่านการเป็นตัวแทน" วัตถุที่สมบูรณ์คือการแสดงสถานะใหม่ของวัตถุที่ถูกสร้างขึ้น

มีการอ้างอิงที่ยอดเยี่ยมสำหรับการออกแบบ API ที่นี่: วิธีปฏิบัติที่ดีที่สุดสำหรับการออกแบบ API Ragful Pragmatic

มันมีคำตอบสำหรับคำถามของคุณที่นี่: การปรับปรุงและการสร้างควรส่งคืนการแสดงทรัพยากร

มันบอกว่า:

เพื่อป้องกันไม่ให้ผู้ใช้ API ต้องกด API อีกครั้งเพื่อรับการอัปเดต API ให้ส่งคืนการแสดง (หรือสร้าง) ที่อัปเดตเป็นส่วนหนึ่งของการตอบกลับ

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


6
แล้วจะส่งคืนวัตถุที่เกี่ยวข้องทั้งชุดอย่างไร ด้วยวิธีนี้การเรียงลำดับที่เป็นไปได้สามารถทำได้ที่ฝั่งเซิร์ฟเวอร์และช่วยให้การใช้งานส่วนหน้าง่ายขึ้น
phil294

2
แต่แนวทางปฏิบัติที่ดีที่สุดเหล่านี้ไม่ได้ดีที่สุด ผู้เขียน statet ที่ HATEOAS ซึ่งมีความสำคัญเช่นเดียวกับหลักการอื่น ๆ จะต้องไม่ถูกใช้เพราะ "มันยังไม่พร้อม" HATEOAS จะไม่ "พร้อม" เพราะหลักการ RESTful ทั้งหมดเป็นเพียงหลักการออกแบบสถาปัตยกรรมไม่ใช่การนำไปปฏิบัติโดยเฉพาะ การอ้างอิงที่ยกมาเป็นเรื่องเกี่ยวกับวิสัยทัศน์ของผู้เขียนเกี่ยวกับ RESTful API ซึ่งไม่ได้สงบเลยเนื่องจากการทิ้ง HATEOAS นั่นเป็นเหตุผลว่าทำไมนี่จึงไม่ใช่การอ้างอิงที่ดีที่สุด :)
24719

1
@marcinn - คุณจะทราบว่าคำถามเดิมมีราคาประมาณ 'ดีที่สุด' ฉันเดาเพราะมีความเห็นในเรื่องนี้เป็นอย่างมาก การอ้างอิงที่ฉันชี้ไปคือสิ่งที่ฉันพบว่าใช้งานได้จริง หากคุณมีการอ้างอิงที่ดีกว่าโปรดแบ่งปัน ฉันเปิดรับการเรียนรู้เพิ่มเติมอยู่เสมอ
grahamesd

@grahamesd การใช้งานเป็นสิ่งที่แตกต่างกันซึ่งการออกแบบสถาปัตยกรรม / รูปแบบ ไม่มีใครสามารถคาดหวังได้ว่า HATEOAS จะพร้อมสักวันหนึ่ง แต่มีโอกาสที่บางคนจะสร้างการนำไปปฏิบัติที่ยอมรับโดยหลาย ๆ คน Vinay ยังเขียนเกี่ยวกับการแมปวิธี http กับ URL และการดำเนินการเฉพาะ (CRUD) ระบุว่าการกำหนดเวอร์ชันโดยการใส่ url เป็นวิธีปฏิบัติเพิ่มเติมเขียนว่าการกรองโดยพารามิเตอร์การสืบค้นเป็นวิธีที่จะไป ... มันใช้ได้ แต่ทั้งหมดนี้มีเพียงเล็กน้อย ทำอย่างไรกับสถาปัตยกรรมสงบ เขาเขียนเกี่ยวกับสัญญาบางประเภท ไม่เป็นไรสำหรับ HTTP API แต่อย่าเรียกว่าสงบ
marcinn

@grahamesd ต่อไปนี้เป็นบทความที่อธิบายถึงสิ่งนี้: - medium.com/@andrea.chiarelli/… - restfulapi.net
marcinn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.