ฉันจะเลือกรหัสสถานะ HTTP ใน REST API สำหรับ“ ยังไม่พร้อมลองอีกครั้งในภายหลัง” ได้อย่างไร [ปิด]


152

ฉันกำลังพัฒนา RESTful API ซึ่งhttp://server/thingyapi/thingyblob/1234ส่งคืนไฟล์ (หรือที่รู้จักว่า "blob") ที่เกี่ยวข้องกับ thingy # 1234 เพื่อดาวน์โหลด แต่อาจเป็นได้ว่ามีการร้องขอในเวลาที่ไฟล์ไม่มีอยู่ในเซิร์ฟเวอร์ แต่ส่วนใหญ่จะสามารถใช้งานได้ในภายหลัง มีกระบวนการแบทช์ในเซิร์ฟเวอร์ที่สร้าง blobs ทั้งหมดสำหรับทุกสิ่ง Thingy 1234 มีอยู่แล้วและมีข้อมูลอื่นนอกเหนือจาก blob แล้ว เซิร์ฟเวอร์ยังไม่ได้สร้างสิ่งที่เป็นก้อน 1234

ฉันไม่ต้องการกลับ 404; สำหรับสิ่งที่ไม่มีอยู่จริง นี่คือสิ่งที่มีอยู่ แต่หยดยังไม่ได้ถูกสร้างขึ้น ค่อนข้างชอบวิดีโอ YouTube ที่ "กำลังดำเนินการ" ฉันไม่คิดว่ารหัสการเปลี่ยนเส้นทางจะเหมาะสมเช่นกัน ไม่มี URL "อื่น ๆ " ให้ลอง

รหัสสถานะ HTTP ที่ถูกต้องที่จะส่งคืนในกรณีดังกล่าวคืออะไร



7
ก่อนอื่นถ้าสิ่งที่ 1234 ยังไม่มีการเป็นตัวแทน GET ใด ๆ มันมีความหมายว่าเป็นทรัพยากร (จากมุมมองของลูกค้า)? ความจริงที่ว่าภายในเซิร์ฟเวอร์มีงานที่อยู่ในคิวเพื่อสร้าง 1234 ดูเหมือนจะไม่ได้หมายความว่ามีทรัพยากร 1234 อยู่ ประการที่สองลูกค้าได้รับ URI ... / thingyblob / 1234 ที่ไหน เซิร์ฟเวอร์อาจไม่ได้จัดเตรียม URI นั้นให้กับลูกค้าจนกว่าทรัพยากรจะสามารถใช้งานได้จริง
Andy Dennie

1
thingy มีคุณสมบัติอื่นที่คุ้มค่าที่จะได้รับมากกว่าหยด มันเป็นเพียงหยดที่ต้องใช้เวลาในการสร้าง ตัวอย่างเช่นไคลเอนต์ได้รับจากเซิร์ฟเวอร์ / thingyapi / thingy / 1234
JCCyC

10
มาตรฐาน HTTP ให้คำแนะนำเกี่ยวกับรหัสสถานะที่จะใช้ในสถานการณ์ใด คำถามนี้จึงไม่ได้จริงๆหลักความคิดเห็นตาม
Raedwald

2
วิธีการเกี่ยวกับ204"ไม่มีเนื้อหา" บ่งชี้ว่าเซิร์ฟเวอร์ประมวลผลคำขอเรียบร้อยแล้วและไม่ส่งคืนเนื้อหาใด ๆ [ในขณะนี้]
Timo

คำตอบ:


77

202 - Acceptedผมขอแนะนำให้ จากเอกสาร :

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


62
-1: นี่จะสมเหตุสมผลสำหรับคำขอที่เริ่มต้นกระบวนการที่สร้าง "thingy # 1234" ในที่สุด แต่ไม่ใช่สำหรับคำขอ GET ที่ออกให้หลังจากนั้นสำหรับ "thingy # 1234" โดยเฉพาะอย่างยิ่ง 202 แสดงให้เห็นว่าเป็นผลมาจากการร้องขอ GET บริการจะส่งข้อมูลสำหรับ "thingy # 1234" ในเวลาต่อมา สิ่งนี้ไม่ถูกต้อง
Sam Harwell

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

3
ฉันจะยืนยันว่า "ยอมรับการประมวลผล" ระบุว่าคุณกำลังบันทึกคำขอที่จะดำเนินการในภายหลัง หากเป็นเพียงการเพิกเฉยคุณควรส่งคืนรหัส 4xx หรือ 5xx เพื่อระบุให้ลูกค้าทราบว่าพวกเขาอาจต้องการลองอีกครั้ง
ลุค

3
102 (การประมวลผล) ดูเหมือนว่ายังเป็นตัวเลือกที่สมเหตุสมผลในบางครั้งแม้ว่าจะอยู่ในข้อมูลจำเพาะของ webdav
akostadinov

2
ไม่เห็นด้วยมากกับคำตอบนี้ เซิร์ฟเวอร์ไม่ได้ส่งคืนสิ่งใดหรือวางแผนที่จะ (ไม่ทำการประมวลผลใด ๆ เนื่องจากคำขอนี้ - ซึ่งไม่ควรได้รับ GET) ดังนั้นทรัพยากรจึงอยู่ในรูปแบบที่ไม่สามารถใช้ได้สำหรับลูกค้า ควรถือว่าเป็นข้อผิดพลาดดังนั้นจึงไม่มีรหัส 2XX ที่เหมาะสม บางสิ่งบางอย่างในพื้นที่ 4XX หรือ 5XX คำขอไม่ได้ "ได้รับการยอมรับสำหรับการดำเนินการ"คำขออยู่ในระหว่างการปฏิบัติถูกยกเลิก
Adam

52

"ปัญหา" เช่นนั้นอยู่บนฝั่งเซิร์ฟเวอร์: ไคลเอนต์ได้ทำการร้องขอที่มีรูปแบบที่ดี แต่เซิร์ฟเวอร์ไม่สามารถตอบสนองได้ ดังนั้นฉันอยากจะ "เซิร์ฟเวอร์ผิดพลาด" รหัสสถานะ 5xx

Quoth RFC 7231 (มาตรฐาน HTTP ปัจจุบันเน้นการเพิ่ม):

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

บันทึก

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

จากรหัสที่มีอยู่ฉันจะบอกว่า503 "การบริการไม่พร้อมใช้งาน"เหมาะสมที่สุด:

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

บันทึก:

  • "มีแนวโน้มที่จะบรรเทาลงหลังจากมีการล่าช้า": จริงสำหรับกรณีของคุณ
  • "โอเวอร์โหลดชั่วคราว": ไม่เป็นความจริงสำหรับกรณีของคุณ แต่อาจเป็นที่ถกเถียงกันอยู่ว่าเซิร์ฟเวอร์ของคุณเร็วขึ้นมากการประมวลผลแบบแบตช์จะทำไปแล้วเมื่อไคลเอนต์ร้องขอดังนั้นจึงเป็น "โอเวอร์โหลด": ลูกค้าร้องขอทรัพยากรที่เร็วกว่าเซิร์ฟเวอร์ พวกเขามีอยู่
  • การลองใหม่เหมาะสำหรับบริการของคุณดังนั้นการตอบกลับของคุณควรรวมRetry-Afterค่าไว้ด้วย คุณสามารถระบุเป็นค่าเวลาดำเนินการโดยประมาณของการดำเนินการแบทช์ครั้งต่อไปหรือช่วงเวลาดำเนินการของกระบวนการแบทช์

การกำหนดรหัสสถานะ 5xx ของคุณเอง (เช่น 591) แม้ว่าได้รับอนุญาตจะมีความหมายที่ผิด:

ลูกค้าจะต้องเข้าใจชั้นเรียนของรหัสสถานะใด ๆ ตามที่ระบุไว้โดยหลักแรกและถือรหัสสถานะที่ไม่รู้จักว่าเทียบเท่ากับรหัสสถานะ x00 ของชั้นเรียนนั้น

ลูกค้าจะถือว่ารหัสสถานะของคุณเป็น500 "Internal Server Error"ซึ่งจะไม่ถูกต้อง


2
ฉันไม่เห็นว่ามันจะดีกว่า 202: benramsey.com/blog/2008/04/…
JCCyC

4
@JCCyC บล็อกของคุณสร้างกรณีที่ดีสำหรับการส่งคืน 202 เพื่อตอบสนองต่อคำขอเพื่อสร้างบางสิ่ง (POST หรือ PUT) คำถามดูเหมือนว่าจะถามเกี่ยวกับสิ่งที่จะกลับมารับ
Raedwald

@JCCyC มันอาจถูกมองว่าเป็นร่มเงาที่แตกต่างจากสภาพที่ไม่พร้อม: ลองนึกภาพอาแจ็กซ์ไปสู่แหล่งข้อมูลนั้นคุณชอบ 202 เป็นสถานะความสำเร็จหรือ 503 เป็นสถานะข้อผิดพลาดหรือไม่? เพื่อให้คุณสามารถเห็นความหมายที่คุณต้องการโดยปริยายในบริบทของการตอบสนองของแอพของคุณต่อการตอบสนอง
2559

นอกจากนี้ฉันชอบแง่มุมที่ใช้งานได้จริงของ "ลองใหม่หลังจาก" ที่ไปได้ดีกับบางสิ่งบางอย่างกำลัง "ไม่พร้อม"
rloth

1
หมายเหตุ: "ลองอีกครั้งหลังจาก" ยังสามารถไปกับ307 - TEMPORARY REDIRECTซึ่งเป็นสิ่งที่ดีถ้าคุณต้องการด้านลูกค้ากำลังเพื่อรอที่อื่น ๆ ในขณะที่ Ressource ของคุณจะถูก "สำเร็จรูป"
rloth

28

ฉันคิดว่า423 - ล็อคสามารถใช้เพื่อวัตถุประสงค์นี้:

รหัสสถานะ 423 (ล็อค) หมายถึงทรัพยากรต้นทางหรือปลายทางของวิธีการถูกล็อค การตอบสนองนี้ควรมีเงื่อนไขที่เหมาะสมหรือรหัส postcondition ที่เหมาะสมเช่น 'ล็อคโทเค็นที่ส่ง' หรือ 'ไม่ล็อคที่ขัดแย้งกัน'


1
คำตอบที่ยอดเยี่ยม! ฉันสงสัยว่าทำไมมันไม่มีผู้โหวตมากขึ้น
lex82

10
อาจเป็นเพราะมันเป็นรหัส WebDAV HTTP?
เตฟาน L

1
จาก akka-http จะมี StatusCode RetryWith = reg (c (449) ("ลองใหม่อีกครั้งด้วย" "ควรทำการร้องขออีกครั้งหลังจากดำเนินการตามความเหมาะสม")) โดยที่การกระทำจะรอและลองอีกครั้ง
ozma

2
ฉันเห็นด้วยกับสิ่งนี้ในหลาย ๆ ฉันมีสถานการณ์ที่คล้ายกัน (ในกรณีของฉันค้นหาจากดัชนีซึ่งอาจยังไม่ได้มีประชากร) ความหมายฉันคิดว่านี่ถูกต้อง อย่างไรก็ตาม RFC สำหรับ 423 รัฐ"คำตอบนี้ควรมีเงื่อนไขที่เหมาะสมหรือรหัส postcondition เช่น 'ล็อคโทเค็น - ส่ง' หรือ 'ไม่มีความขัดแย้งล็อค' ไม่แน่ใจว่าจะสมัครได้อย่างไรที่นี่ และโดยส่วนตัวแล้วฉันจะไปกับ 409 Conflict แต่นั่นถูกลดระดับลงโดยไม่มีความคิดเห็น - ไม่แน่ใจทำไม
อดัม

22

ฉันไม่ต้องการกลับ 404; สำหรับสิ่งที่ไม่มีอยู่จริง

URL ไม่สอดคล้องกับคำขอสิ่งที่ต้องการ

http://server/thingyapi/thingyblob/1234

ลูกค้ากำลังขอข้อมูลบางอย่างที่ไม่มีอยู่ หากมีอยู่คุณจะต้องมอบให้

404


1
ฉันดีใจที่มีคนพูดแบบนี้! ฉันไม่อยากจะเชื่อว่ามีคนจำนวนมากที่คิดว่า503เป็นการตอบสนองที่เหมาะสม ไม่ต้องพูดถึงคำแนะนำแปลก ๆ อื่น ๆ
Jason Desrosiers

แม้ว่าฉันจะเห็นด้วยว่า 404 เป็นคำตอบที่เหมาะสมที่สุดที่นี่ แต่ก็ไม่ได้ตอบคำถามของ OP ว่าจะระบุได้อย่างไรเมื่อ :-) ฉันคิดว่าฟิลด์ Retry-After ดูเหมือนจะเป็นตัวเลือกที่ดีที่สุด แต่สามารถใช้กับรหัส 503 และ 3xx อย่างเป็นทางการเท่านั้น @ Jason: ฉันคิดว่าจะอธิบายคำแนะนำแปลก ๆ
Ron Deijkers

ฉันคิดว่านี่เป็นคำตอบที่ดีที่สุด คุณได้รับอนุญาตให้ส่งคืนเนื้อหาในการตอบกลับ 404 ร่างกายสามารถระบุได้ว่าสิ่งที่จะมีอยู่ในภายหลัง หรือใช้ส่วนหัว Retry-After เช่นกัน มาตรฐานจะต้องยืดออกไปเล็กน้อยเพราะนี่ไม่ครอบคลุมกรณีนี้เป็นอย่างดี
WW

4
ผู้คนเคยชินกับหน้าความหมาย 404 เกินไปไม่พบว่าพวกเขาไม่สามารถแยกความแตกต่างทางตรรกะได้ว่าเมื่ออยู่ในบริบทของ API
The Muffin Man

1
นี่คือ sooooo 404 Thingyblob ยังไม่มีอยู่หรือตลอดไป .. สำหรับ http ที่ไม่เกี่ยวข้องหากจะมีให้บริการ ในขณะนี้ยังไม่มีอยู่และ 404 เมื่อมันพร้อมใช้งานจะมีปัญหาอื่นซึ่งสามารถแก้ไขได้โดยการผลัก mesage จากเซิร์ฟเวอร์ไปยังไคลเอนต์ในสิ่งที่มีอยู่: 1234 ทำการรับอีกครั้งและ voila ..
100r

21

ตัวเลือกอื่น: 503 - Service Unavailable.


5
ตาม W3Cไม่ใช่สิ่งที่คุณต้องการพูดกับลูกค้า (แม้ว่าจะหมายถึง "กลับมา" ในบางลักษณะ): "เซิร์ฟเวอร์ไม่สามารถจัดการคำขอได้ในขณะนี้เนื่องจากเซิร์ฟเวอร์ทำงานหนักเกินไปหรือการบำรุงรักษาเซิร์ฟเวอร์ นี่เป็นเงื่อนไขชั่วคราวซึ่งจะบรรเทาลงหลังจากมีการหน่วงเวลาบางครั้งหากทราบความยาวของการหน่วงเวลาอาจถูกระบุในส่วนหัว Retry-After หากไม่ได้รับการลองใหม่ - หลังจากไคลเอนต์ SHOULD จะจัดการกับการตอบสนองเช่นเดียวกับ 500 คำตอบ "
skalee

4
บริการไม่พร้อมใช้งานบริการพร้อมใช้งาน แต่การประมวลผลไม่สมบูรณ์ ดังนั้น 503 อาจไม่ใช่ความคิดที่ดี
Ishtiaque Khan

17

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

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


3
แม้ว่าจะได้รับอนุญาตหากไคลเอนต์ไม่ได้ใช้งานการสนับสนุนสำหรับส่วนหัวลองใหม่หลังจากนั้นการเปลี่ยนเส้นทาง 3xx ไปที่หน้าเดียวกันในที่สุดอาจสิ้นสุดใน 503 ... (ทางเลือกที่มีส่วนหัว Retry-After แน่นอน)
Ron Deijkers

1
การลองใหม่หลังจากนั้นใช้ได้กับ HTTP 429 "คำขอมากเกินไป" ซึ่งเพิ่มโดย RFC 6585 (เมษายน 2012) สิ่งนี้อาจเหมาะสมถ้าเหตุผลของทรัพยากรที่ยังไม่พร้อมคือไคลเอนต์ให้เซิร์ฟเวอร์ทำงานมากเกินไป
สิลาสเอส. บราวน์

8

409 ความขัดแย้ง

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

สิ่งนี้อาจเหมาะสม

หากคุณไม่สามารถทำตามคำขอโดยส่งคืนข้อมูล - ไม่ใช่ความสำเร็จ ฉันคิดว่า 202 แนะนำว่าเซิร์ฟเวอร์ได้รอคำขอและจะตอบสนองคำขอในภายหลัง แต่ในกรณีของคุณคำขอเป็นข้อมูลตอนนี้และล้มเหลว หากคุณลองอีกครั้งในภายหลังมันเป็นคำขอที่แตกต่างกัน

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


2
ไม่แน่ใจว่าทำไมสิ่งนี้ถึงถูกโหวต ดูเหมือนว่าคำตอบที่ถูกต้องสำหรับฉัน จาก RFC: "รหัสสถานะ 409 (ความขัดแย้ง) บ่งชี้ว่าการร้องขอไม่สามารถเสร็จสมบูรณ์ได้เนื่องจากความขัดแย้งกับสถานะปัจจุบันของทรัพยากรเป้าหมายรหัสนี้ใช้ในสถานการณ์ที่ผู้ใช้อาจจะสามารถแก้ไขข้อขัดแย้งและ ส่งคำขออีกครั้ง "คุณขอทรัพยากรที่เซิร์ฟเวอร์ไม่สามารถส่งคืนได้เนื่องจากเซิร์ฟเวอร์อยู่ในกระบวนการอัปเดตทรัพยากรนั้น - เช่นเนื่องจากสถานะปัจจุบันของทรัพยากร ลูกค้าสามารถแก้ไขปัญหานี้ได้โดยการรอและส่งใหม่
Adam

1
@ อดัมฉันคิดว่าความหมายใน "ผู้ใช้อาจจะสามารถแก้ไขข้อขัดแย้ง" คือสิ่งที่เกี่ยวกับการส่งอีกครั้งจะแตกต่างกันไปกว่ารอ
นักพัฒนาแบบองค์รวม

3

501 - ไม่ดำเนินการ

เหมือนกับว่ามันฟังตรงไหน คุณลักษณะที่ยังไม่ได้ใช้งาน แต่หมายถึงความพร้อมใช้งานในอนาคต

นี่คือการเชื่อมโยงไปยังบทสรุปของข้อผิดพลาด 5xx


4
สำหรับคำถามนี้ดูเหมือนว่าจะมีฟีเจอร์อยู่ แต่รายการที่ร้องขอไม่ได้
ลุค

คำอธิบายของ @Luke 501 จากลิงก์ในคำตอบของฉัน '... มันขาดความสามารถในการตอบสนองคำขอ โดยปกติสิ่งนี้แสดงถึงความพร้อมในอนาคต ' นี่เป็นการตอบสนองที่ OP ต้องการ ไม่ว่าข้อมูลนั้นจะอยู่ในเซิร์ฟเวอร์หรือฐานข้อมูลก็ตาม ผลลัพธ์ขั้นสุดท้ายคือไม่สามารถเข้าถึงได้ผ่าน API ในตอนนี้ ดังนั้น API ไม่สามารถตอบสนองคำขอได้ แต่ต้องการบอกเป็นนัยว่าจะมีให้บริการในอนาคตผ่านรหัส http
ด่าน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.