รหัสสถานะ HTTP ใดที่จะส่งคืนหากการกระทำหลายอย่างเสร็จสิ้นด้วยสถานะที่แตกต่างกัน


72

ฉันกำลังสร้าง API ที่ผู้ใช้สามารถขอให้เซิร์ฟเวอร์ดำเนินการหลายอย่างในคำขอ HTTP เดียว ผลลัพธ์ถูกส่งคืนเป็นอาร์เรย์ JSON โดยมีหนึ่งรายการต่อการดำเนินการ

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

หากมีหนึ่งคำขอต่อการกระทำฉันจะส่งคืนรหัสสถานะ 200, 422 และ 500 ตามลำดับ แต่ตอนนี้เมื่อมีคำขอเพียงครั้งเดียวฉันควรส่งรหัสสถานะใด

ตัวเลือกบางอย่าง:

  • ส่งคืน 200 เสมอและให้ข้อมูลรายละเอียดเพิ่มเติมในร่างกาย
  • อาจปฏิบัติตามกฎข้างต้นเฉพาะเมื่อมีมากกว่าหนึ่งการกระทำในคำขอ?
  • อาจส่งคืน 200 หากคำขอทั้งหมดสำเร็จมิฉะนั้น 500 (หรือรหัสอื่น)
  • เพียงใช้หนึ่งคำขอต่อการกระทำและยอมรับค่าใช้จ่ายเพิ่มเติม
  • มีอะไรที่แตกต่างไปจากเดิมอย่างสิ้นเชิง?

3
คำถามของคุณทำให้ฉันคิดถึงอีกเรื่องหนึ่ง: programmers.stackexchange.com/questions/309147/ …
AilurusFulgens

7
มีความเกี่ยวข้องเล็กน้อยเช่นกัน: programmers.stackexchange.com/questions/305250/… (ดูคำตอบที่ยอมรับเกี่ยวกับการแยกระหว่างรหัสสถานะ HTTP และรหัสแอปพลิเคชัน)

4
อะไรคือข้อดีที่คุณจะได้รับจากการจัดกลุ่มคำขอเหล่านั้นด้วยกัน? มันเกี่ยวกับตรรกะทางธุรกิจเช่นธุรกรรมมากกว่าทรัพยากรหลายอย่างหรือเกี่ยวกับประสิทธิภาพหรือไม่? หรืออย่างอื่น?
Luc Franken

5
ตกลงในกรณีนี้ฉันขอแนะนำอย่างยิ่งให้ปรับปรุงประสิทธิภาพนั้นในส่วนอื่น ๆ ลองสิ่งต่าง ๆ เช่น UI ที่มองโลกในแง่ดีขอแบทช์แคช ฯลฯ ก่อนนำความซับซ้อนนี้ไปใช้กับเลเยอร์ธุรกิจของคุณ คุณมีข้อมูลเชิงลึกที่ชัดเจนว่าคุณเสียเวลามากที่สุดหรือไม่?
Luc Franken

4
... อย่าหวังเกินกว่าที่คนจะมองสถานะเหล่านั้นได้อย่างถูกต้อง โปรแกรมส่วนใหญ่จะตรวจสอบโปรแกรมที่พบบ่อยที่สุดเท่านั้นและล้มเหลวหรือทำงานผิดปกติหากได้รับรหัสสถานะที่ไม่คาดคิด (ฉันจำได้ว่ามีการนำเสนอที่ DefCon เกี่ยวกับการปกป้องไซต์ของคุณจากโปรแกรมรวบรวมข้อมูลโดยส่งสถานะการออกแบบสุ่มซึ่งเบราว์เซอร์จะข้ามและแสดงสาเหตุที่โปรแกรมรวบรวมข้อมูลบางครั้งเป็นข้อผิดพลาดและหยุดการรวบรวมข้อมูลในส่วนนั้นของเว็บไซต์)
บากูริว

คำตอบ:


21

คำตอบสั้น ๆ โดยตรง

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


คำตอบที่ยาวและปรัชญา

คุณกำลังประสบกับภาวะที่กลืนไม่เข้าคายไม่ออกนี้เพราะคุณเบี่ยงเบนความสนใจจากสิ่งที่ HTTP ได้รับการออกแบบมา คุณไม่ได้มีปฏิสัมพันธ์กับมันเพื่อจัดการทรัพยากร แต่คุณใช้มันเป็นวิธีการรีโมตเมธอดแบบรีโมต (ซึ่งไม่แปลกมาก แต่ทำงานได้ไม่ดีโดยไม่มีโครงร่างที่รับมาก่อน)

จากที่กล่าวมาข้างต้นและหากปราศจากความกล้าที่จะเปลี่ยนคำตอบนี้ให้เป็นแนวทางที่มีความเห็นยาว ๆ ต่อไปนี้คือโครงการ URI ที่สอดคล้องกับแนวทางการจัดการทรัพยากร:

  • /tasks
    • GET แสดงรายการงานทั้งหมดเลขหน้า
    • POST เพิ่มงานเดียว
  • /tasks/task/[id]
    • GET ตอบสนองด้วยวัตถุสถานะของงานเดียว
    • DELETE ยกเลิก / ลบงาน
  • /tasks/groups
    • GET แสดงรายการกลุ่มงานทั้งหมดแบ่งหน้า
    • POST เพิ่มกลุ่มของงาน
  • /tasks/groups/group/[id]
    • GET ตอบสนองด้วยสถานะของกลุ่มงาน
    • DELETE ยกเลิก / ลบกลุ่มงาน

โครงสร้างนี้พูดคุยเกี่ยวกับทรัพยากรไม่ใช่เกี่ยวกับพวกเขา สิ่งที่กำลังทำอยู่กับทรัพยากรคือความกังวลของบริการอื่น

ประเด็นสำคัญอีกข้อหนึ่งที่ควรทำคือไม่แนะนำให้บล็อกในตัวจัดการคำร้องขอ HTTP เป็นเวลานาน เช่นเดียวกับ UI อินเตอร์เฟส HTTP ควรตอบสนอง - ในช่วงเวลาที่มีขนาดของการสั่งซื้อช้าลงเล็กน้อย (เนื่องจากเลเยอร์นี้เกี่ยวข้องกับ IO)

การย้ายไปสู่การออกแบบอินเตอร์เฟส HTTP ที่จัดการทรัพยากรอย่างเข้มงวดนั้นอาจเป็นเรื่องยากเหมือนกับการย้ายงานออกจากเธรด UI เมื่อมีการคลิกปุ่ม มันต้องการให้เซิร์ฟเวอร์ HTTP สื่อสารกับบริการอื่น ๆ เพื่อดำเนินงานแทนการดำเนินการในการจัดการการร้องขอ นี่ไม่ใช่การใช้งานแบบตื้น แต่เป็นการเปลี่ยนทิศทาง


ตัวอย่างบางส่วนของวิธีการใช้รูปแบบ URI ดังกล่าว

การดำเนินงานเดียวและความคืบหน้าการติดตาม:

  • POST /tasks กับงานที่จะดำเนินการ
    • GET /tasks/task/[id]จนกว่าวัตถุตอบกลับcompletedจะมีค่าเป็นบวกในขณะที่แสดงสถานะ / ความคืบหน้าในปัจจุบัน

ดำเนินงานเดียวและรอความสำเร็จ:

  • POST /tasks กับงานที่จะดำเนินการ
    • GET /tasks/task/[id]?awaitCompletion=trueจนกว่าจะcompletedมีค่าเป็นบวก (น่าจะหมดเวลาซึ่งเป็นเหตุผลว่าทำไมจึงควรวนซ้ำ)

การดำเนินงานกลุ่มงานและความคืบหน้าการติดตาม:

  • POST /tasks/groups กับกลุ่มของงานที่จะดำเนินการ
    • GET /tasks/groups/group/[groupId]จนกว่าcompletedคุณสมบัติของวัตถุตอบกลับจะมีค่าแสดงสถานะงานแต่ละงาน (ตัวอย่างเช่น 3 งานจาก 5 รายการ)

การร้องขอการเรียกใช้งานสำหรับกลุ่มงานและรอให้การดำเนินการเสร็จสิ้น:

  • POST /tasks/groups กับกลุ่มของงานที่จะดำเนินการ
    • GET /tasks/groups/group/[groupId]?awaitCompletion=true จนกว่าจะตอบกลับด้วยผลลัพธ์ที่แสดงว่าเสร็จสิ้น (น่าจะหมดเวลาซึ่งเป็นเหตุผลว่าทำไมจึงควรวนซ้ำ)

ฉันคิดว่าการพูดถึงความหมายที่เหมาะสมคือวิธีที่เหมาะสมในการเข้าถึง ขอบคุณ!
Anders

2
ฉันจะเสนอคำตอบนี้หากยังไม่เคยไป มันเป็นไปไม่ได้ที่จะทำให้คำขอหลายรายการในคำขอ HTTP เดียว ในทางกลับกันมันเป็นไปได้อย่างสมบูรณ์แบบที่จะสร้างคำขอ HTTP เดียวซึ่งระบุว่า "ดำเนินการต่อไปนี้และแจ้งให้เราทราบว่าผลลัพธ์คืออะไร" และนี่คือสิ่งที่เกิดขึ้นที่นี่
Martin Kochanski

ฉันจะยอมรับคำตอบนี้แม้เจ้าจะอยู่ห่างไกลจากการโหวตมากที่สุด ในขณะที่คำตอบอื่น ๆ ก็ดีเช่นกันฉันคิดว่านี่เป็นเหตุผลเดียวที่เกี่ยวกับความหมายของ HTTP
Anders

87

คะแนนของฉันจะแยกงานเหล่านี้ออกเป็นคำขอแยกต่างหาก แต่ถ้ารอบการเดินทางมากเกินไปกังวลผมไม่เจอการตอบสนอง HTTP รหัส 207 - หลายสถานะ

คัดลอก / วางจากลิงค์นี้:

การตอบสนองหลายสถานะสื่อถึงข้อมูลเกี่ยวกับทรัพยากรหลายอย่างในสถานการณ์ที่อาจมีรหัสสถานะหลายรหัสที่เหมาะสม เนื้อความการตอบสนองหลายสถานะเริ่มต้นคือเอนทิตีข้อความ / xml หรือแอปพลิเคชัน / xml HTTP ที่มีองค์ประกอบราก 'multistatus' องค์ประกอบเพิ่มเติมประกอบด้วยรหัสสถานะ 200, 300, 400 และ 500 ซีรี่ส์ที่สร้างขึ้นระหว่างการเรียกใช้เมธอด รหัสสถานะ 100 ซีรี่ส์ไม่ควรบันทึกในองค์ประกอบ XML 'การตอบสนอง'

แม้ว่าจะใช้ '207' เป็นรหัสสถานะการตอบสนองโดยรวมผู้รับต้องปรึกษาเนื้อหาของเนื้อหาการตอบสนอง multistatus สำหรับข้อมูลเพิ่มเติมเกี่ยวกับความสำเร็จหรือความล้มเหลวของการดำเนินการวิธีการ อาจใช้การตอบสนองในความสำเร็จความสำเร็จบางส่วนและในสถานการณ์ที่ล้มเหลว


22
207ดูเหมือนจะเป็นสิ่งที่ OP ต้องการ แต่ฉันต้องการเน้นว่ามันเป็นความคิดที่ไม่ดีที่จะมีวิธีการแบบหลายคำขอในหนึ่งนี้ หากความกังวลเกี่ยวกับประสิทธิภาพนั้นคุณควรสร้างสถาปัตยกรรมสำหรับระบบคลาวด์ที่ปรับขนาดได้ในแนวนอน (ซึ่งเป็นสิ่งที่ระบบฐาน HTTP นั้นยอดเยี่ยม)
David Grinberg

44
@DavidGrinberg ฉันไม่เห็นด้วยอีกเลย หากการกระทำของแต่ละบุคคลมีราคาถูกดังนั้นค่าใช้จ่ายในการจัดการคำขออาจมีราคาสูงกว่าการดำเนินการเอง ข้อเสนอแนะของคุณอาจนำไปสู่สถานการณ์ที่การอัพเดตหลายแถวในฐานข้อมูลเสร็จสิ้นโดยใช้ธุรกรรมแยกต่างหากต่อแถวเพราะแต่ละแถวจะถูกส่งเป็นคำขอแยกต่างหาก สิ่งนี้ไม่เพียง แต่ไร้ประสิทธิภาพอย่างน่ากลัวเท่านั้น แต่ยังหมายความว่าจะไม่สามารถอัปเดตหลาย ๆ แถวแบบเป็นอะตอมถ้าจำเป็น การปรับสเกลแนวนอนเป็นสิ่งสำคัญ แต่ไม่สามารถทดแทนการออกแบบที่มีประสิทธิภาพ
kasperd

4
กล่าวอย่างดีและชี้ให้เห็นถึงปัญหาทั่วไปของการใช้งาน REST API ที่ทำโดยคนที่ไม่รู้ความจริงของความต้องการทางธุรกิจเช่นประสิทธิภาพและ / หรืออะตอมมิก ยกตัวอย่างเช่นข้อมูลจำเพาะ OData REST มีรูปแบบแบทช์สำหรับการดำเนินการหลายอย่างในการเรียกครั้งเดียว - มีความต้องการที่แท้จริงสำหรับมัน
TomTom

8
@TomTom OP ไม่ต้องการอะตอมมิก นั่นจะเป็นสิ่งที่ง่ายกว่ามากในการออกแบบเนื่องจากมีสถานะการทำงานปรมาณูเพียงสถานะเดียว นอกจากนี้สเปค HTTP ยังช่วยให้สามารถทำการแบตช์เพื่อประสิทธิภาพผ่าน HTTP / 2 มัลติเพล็กซิ่ง (โดยปกติการรองรับ HTTP / 2 เป็นอีกเรื่องหนึ่ง
พอลเดรเปอร์

2
@ David เคยทำงานเกี่ยวกับปัญหา HPC บางอย่างในอดีตจากประสบการณ์ของฉันค่าใช้จ่ายในการส่งไบต์เดียวก็ค่อนข้างจะเหมือนกับการส่งหนึ่งพัน (สื่อการถ่ายโอนที่แตกต่างกันมีค่าใช้จ่ายที่แตกต่างกันอย่างแน่นอน ดังนั้นหากประสิทธิภาพมีความกังวลฉันไม่เห็นว่าการส่งคำขอหลายรายการจะไม่มีค่าใช้จ่ายจำนวนมาก ตอนนี้ถ้าคุณสามารถมัลติเพล็กหลายคำขอผ่านการเชื่อมต่อเดียวกันปัญหานี้จะหายไป แต่เมื่อฉันเข้าใจแล้วนั่นเป็นเพียงตัวเลือกที่มี HTTP / 2 และการสนับสนุนสำหรับมันค่อนข้าง จำกัด หรือฉันกำลังพลาดอะไรอยู่?
Voo

24

แม้ว่าจะมีหลายสถานะเป็นตัวเลือกฉันจะส่งคืน 200 (ดีทั้งหมด) ถ้าคำขอทั้งหมดประสบความสำเร็จและข้อผิดพลาด (500 หรืออาจ 207) เป็นอย่างอื่น

กรณีมาตรฐานควรเป็น 200 - ทุกอย่างได้ผล และลูกค้าควรตรวจสอบเท่านั้น และเฉพาะกรณีที่เกิดข้อผิดพลาดคุณสามารถส่งคืน 500 (หรือ 207) ฉันคิดว่า 207 เป็นตัวเลือกที่ถูกต้องในกรณีที่มีข้อผิดพลาดอย่างน้อยหนึ่งข้อ แต่ถ้าคุณเห็นแพคเกจทั้งหมดเป็นธุรกรรมเดียวคุณสามารถส่ง 500 ได้ - ลูกค้าจะต้องการตีความข้อความแสดงข้อผิดพลาดด้วยวิธีใดวิธีหนึ่ง

ทำไมไม่ส่ง 207 เสมอ - เพราะกรณีมาตรฐานควรง่ายและเป็นมาตรฐาน ในขณะที่กรณีพิเศษอาจเป็นกรณีพิเศษ ลูกค้าควรอ่านเนื้อหาของการตอบสนองและทำการตัดสินใจที่ซับซ้อนเพิ่มเติมหากสถานการณ์พิเศษรับประกัน


6
ฉันไม่ค่อยเห็นด้วย หากคำขอย่อยที่ 1 และ 3 ประสบความสำเร็จคุณจะได้รับทรัพยากรแบบรวมและต้องตรวจสอบการตอบกลับแบบรวมอยู่ดี คุณมีอีกหนึ่งกรณีที่ต้องพิจารณา ถ้า response = 200 หรือ subresponse 1 = 200 ดังนั้นคำขอ 1 สำเร็จ หากการตอบสนอง = 200 หรือ subresponse 2 = 200 ดังนั้นคำขอ 2 จะประสบความสำเร็จเป็นต้นแทนที่จะเพียงทดสอบการตอบกลับย่อย
gnasher729

1
@ gnasher729 มันขึ้นอยู่กับแอปพลิเคชันจริงๆ ฉันจินตนาการถึงการกระทำที่ขับเคลื่อนโดยผู้ใช้ซึ่งจะไหลไปสู่ขั้นตอนต่อไปด้วย (ทุกอย่าง ok) เมื่อคำขอทั้งหมดประสบความสำเร็จ - หากมีสิ่งใดที่ผิดพลาด (สถานะโลก <= 200) คุณต้องแสดงข้อผิดพลาดโดยละเอียดและเปลี่ยนเวิร์กโฟลว์และต้องการการตรวจสอบเพียงครั้งเดียวสำหรับแต่ละคำขอย่อยเนื่องจากคุณอยู่ในฟังก์ชัน "handleMixedState" ไม่ใช่ฟังก์ชัน "handleAllOk" .
Falco

มันขึ้นอยู่กับความหมายของมันจริงๆ ตัวอย่างเช่นฉันมีปลายทางที่ควบคุมกลยุทธ์การซื้อขาย คุณสามารถ "เริ่มต้น" รายการตัวระบุได้ในการวิ่งครั้งเดียว ผลตอบแทน 200 หมายถึงการดำเนินการ (ประมวลผล) สำเร็จ - แต่อาจไม่สำเร็จทั้งหมด ซึ่ง btw. ไม่สามารถเห็นได้ในผลลัพธ์ทันที (ซึ่งจะเริ่ม) เนื่องจากการเริ่มต้นอาจใช้เวลาสักครู่ ความหมายในการดำเนินการหลายสายขึ้นอยู่กับสถานการณ์
TomTom

ฉันก็น่าจะส่ง 500 ถ้ามีปัญหาทั่วไป (เช่นฐานข้อมูลลง) ดังนั้นเซิร์ฟเวอร์ไม่ได้ลองแต่ละคำขอ แต่ก็สามารถกลับข้อผิดพลาดทั่วไป - เนื่องจากมีผลลัพธ์ที่แตกต่างกัน 3 แบบสำหรับผู้ใช้ 1. ทั้งหมดตกลง 2. ปัญหาทั่วไปไม่มีอะไรทำงาน 3. คำขอบางอย่างล้มเหลว -> ซึ่งมักจะนำไปสู่การไหลเวียนของโปรแกรมที่แตกต่างอย่างสิ้นเชิง
Falco

1
ตกลงดังนั้นวิธีการหนึ่งจะเป็น: 207 = แต่ละสถานะสำหรับแต่ละคำขอ สิ่งอื่น: สถานะที่ส่งคืนจะมีผลกับคำขอแต่ละคำขอ เหมาะสมสำหรับ 200, 401, ≥ 500.
gnasher729

13

ทางเลือกหนึ่งคือการส่งคืนรหัสสถานะ 200 จากนั้นส่งคืนข้อผิดพลาดเฉพาะในเนื้อหาเอกสาร JSON ของคุณ นี่คือวิธีที่ API บางตัวได้รับการออกแบบ (พวกเขาจะส่งคืนรหัสสถานะ 200 เสมอและส่งข้อผิดพลาดในเนื้อหา) สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการต่าง ๆ โปรดดูที่http://archive.oreilly.com/pub/post/restful_error_handling.html


2
ในกรณีนี้ฉันชอบความคิดในการใช้200เพื่อระบุว่าทั้งหมดดีคำขอได้รับและถูกต้องแล้วใช้ JSON เพื่อให้รายละเอียดเกี่ยวกับสิ่งที่เกิดขึ้นในคำขอนั้น (เช่นผลลัพธ์ของธุรกรรม)
rickcnagy

4

ฉันคิดว่า neilsimp1 นั้นถูกต้อง แต่ฉันขอแนะนำการออกแบบใหม่ของข้อมูลที่ถูกส่งในลักษณะที่คุณสามารถส่ง206 - Acceptedและประมวลผลข้อมูลในภายหลัง บางทีด้วยการเรียกกลับ

ปัญหาของการพยายามส่งการกระทำหลายรายการในคำขอเดียวคือข้อเท็จจริงที่ว่าการกระทำแต่ละรายการควรมีสถานะเป็นของตัวเอง

ดูการนำเข้า CSV (ฉันไม่รู้จริงๆว่า OP คืออะไรเกี่ยวกับ แต่มันเป็นรุ่นธรรมดา) โพสต์ CSV และรับ 206 จากนั้นสามารถนำเข้า CSV ในภายหลังและคุณสามารถรับสถานะการนำเข้าด้วย GET (200) เทียบกับ URL ที่แสดงข้อผิดพลาดต่อแถว

POST /imports/ -> 206
GET  /imports/1 -> 200
GET  /imports/1/errors -> 200 -> Has a list of errors

รูปแบบเดียวกันนี้สามารถนำไปใช้กับชุดงานจำนวนมากได้

POST /operations/ -> 206
GET  /operations/1 -> 200
GET  /operations/1/errors -> 200 - > Has a list of errors.

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


2

มีคำตอบที่ดีอยู่แล้วที่นี่ แต่ขาดไปด้านหนึ่ง:

สัญญาที่ลูกค้าคาดหวังคืออะไร

รหัสส่งคืน HTTP ควรระบุอย่างน้อยความแตกต่างของความสำเร็จ / ความล้มเหลวและดังนั้นจึงมีบทบาทใน "ข้อยกเว้นของคนจน" จากนั้น 200 หมายถึง "สัญญาสมบูรณ์ครบถ้วน" และ 4xx หรือ 5xx แสดงว่าไม่สามารถปฏิบัติตามได้

อย่างไร้เดียงสาฉันคาดหวังว่าสัญญาการร้องขอหลายการกระทำของคุณจะเป็น "ทำงานของฉันทั้งหมด" และหากหนึ่งในนั้นล้มเหลวคำขอจะไม่ประสบความสำเร็จ โดยปกติแล้วในฐานะลูกค้าฉันเข้าใจว่า 200 เป็น "ทุกอย่างโอเค" และรหัสจากครอบครัว 400 และ 500 บังคับให้ฉันคิดเกี่ยวกับผลที่ตามมาของความล้มเหลว (บางส่วน) ดังนั้นใช้ 200 สำหรับ "งานทั้งหมดทำ" และ 500 บวกการตอบสนองเชิงพรรณนาในกรณีที่มีความล้มเหลวบางส่วน

สัญญาสมมุติอาจแตกต่างกันคือ "ลองทำทุกอย่าง" ถ้าอย่างนั้นการกระทำก็ล้มเหลว ดังนั้นคุณจะส่งคืน 200 เอกสารผลลัพธ์ที่คุณพบข้อมูลความสำเร็จ / ความล้มเหลวสำหรับงานแต่ละงาน

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

สิ่งสำคัญขั้นสุดท้าย: คุณสื่อสารการตัดสินใจสัญญาของคุณกับลูกค้าอย่างไร เช่นใน Java ฉันจะใช้ชื่อวิธีเช่น "doAll ()" หรือ "tryToDoAll ()" ใน HTTP คุณสามารถตั้งชื่อ URL ปลายทางได้โดยหวังว่าผู้พัฒนาไคลเอ็นต์ของคุณจะเห็นอ่านและเข้าใจการตั้งชื่อ (ฉันจะไม่เดิมพัน) อีกเหตุผลหนึ่งในการเลือกสัญญาที่น่าประหลาดใจน้อยที่สุด


0

ตอบ:

เพียงใช้หนึ่งคำขอต่อการกระทำและยอมรับค่าใช้จ่ายเพิ่มเติม

รหัสสถานะอธิบายสถานะของการดำเนินการหนึ่งครั้ง ดังนั้นจึงเหมาะสมที่จะมีหนึ่งการดำเนินการต่อการร้องขอ

การดำเนินการที่เป็นอิสระหลายครั้งจะแบ่งหลักการที่โมเดลการตอบกลับคำร้องขอและรหัสสถานะขึ้นอยู่กับ คุณกำลังต่อสู้กับธรรมชาติ

HTTP / 1.1 และ HTTP / 2 ทำให้โอเวอร์เฮดของคำร้องขอ HTTP ต่ำกว่ามาก ฉันประเมินว่ามีสถานการณ์น้อยมากที่แนะนำให้เลือกแบทช์อิสระ


ที่กล่าวว่า

(1) คุณสามารถทำการแก้ไขหลายรายการด้วยคำขอ PATCH ( RFC 5789 ) อย่างไรก็ตามสิ่งนี้ต้องการการเปลี่ยนแปลงที่ไม่เป็นอิสระ พวกเขาจะใช้ atomically (ทั้งหมดหรือไม่มีอะไร)

(2) คนอื่น ๆ ได้ชี้ให้เห็นรหัส 207 หลายสถานะ อย่างไรก็ตามสิ่งนี้ถูกกำหนดไว้สำหรับ WebDAV ( RFC 4918 ) ซึ่งเป็นส่วนขยายของ HTTP เท่านั้น

รหัสสถานะ 207 (หลายสถานะ) ให้สถานะสำหรับการดำเนินงานอิสระหลายรายการ (ดูส่วนที่ 13 สำหรับข้อมูลเพิ่มเติม)

...

การตอบสนองหลายสถานะสื่อถึงข้อมูลเกี่ยวกับทรัพยากรหลายอย่างในสถานการณ์ที่อาจมีรหัสสถานะหลายรหัสที่เหมาะสม องค์ประกอบ 'multistatus' รูท [XML] เก็บองค์ประกอบ 'การตอบสนอง' เป็นศูนย์หรือมากกว่าในลำดับใด ๆ แต่ละรายการมีข้อมูลเกี่ยวกับทรัพยากรแต่ละรายการ

การตอบสนอง 207 WebDAV XML จะแปลกเหมือนเป็ดใน aa non-WebDAV API อย่าทำอย่างนี้


1
คุณยืนยันว่า @Anders มีปัญหา XYเป็นหลัก คุณอาจพูดถูก แต่น่าเสียดายที่นั่นหมายความว่าคุณยังไม่ได้ตอบคำถามที่เขาถามจริง ๆ (รหัสสถานะใดที่จะใช้สำหรับคำขอแบบหลายแอ็คชัน)
Azuaron

2
@Azuaron เข็มขัดชนิดใดที่ดีที่สุดสำหรับการตีเด็ก ฉันคิดว่า "N / A" เป็นคำตอบที่อนุญาต นอกจากนี้แอนเดรสยังรวมคำขอจำนวนมากไว้ในรายการความคิดของเขา ฉันสนับสนุนตัวเลือกนั้นอย่างสุดใจ
พอลเดรเปอร์

ฉันคิดถึงที่เขาระบุไว้ ในกรณีนั้นฉันขอยืนยันว่ามันเป็นคำถามที่โง่เขลาเกียรติของคุณ!
Azuaron

1
@ Azuaron ฉันคิดว่านี่เป็นคำตอบที่ถูกต้อง ถ้าฉันทำผิดทั้งหมดฉันต้องการใครซักคนพูดและอย่าให้คำแนะนำเกี่ยวกับวิธีขับหน้าผาออกมาให้ดีที่สุด
Anders

1
ไม่มีข้อห้ามในการส่ง JSON ในการตอบสนอง 207 ตราบใดที่ส่วนหัว Content-Type ได้รับการตั้งค่าอย่างเหมาะสมและตรงกับสิ่งที่ลูกค้าถาม (ยอมรับส่วนหัว)
dolmen

0

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

ในฐานะลูกค้าที่ใช้ API ฉันสามารถจัดการกับความสำเร็จหรือความล้มเหลวได้อย่างสมบูรณ์ในการเรียก API ความสำเร็จบางส่วนนั้นยากที่จะจัดการเนื่องจากฉันจะต้องจัดการกับสถานะที่เป็นไปได้ทั้งหมด


2
ฉันสมมติว่าคำขอควรเป็นอะตอมเขาจะไม่โพสต์คำถามนี้
แอนดี้

@ Andy บางที แต่คุณไม่สามารถสรุปได้ว่าเขาพิจารณาถึงผลกระทบทั้งหมดของการออกแบบดังกล่าวแล้ว
คณบดี

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