ตัวอย่างเช่นคุณเรียกใช้คำขอ GET users/9
แต่ไม่มีผู้ใช้ที่มี ID # 9 รหัสตอบกลับที่ดีที่สุดคืออะไร
- 200 ตกลง
- 202 ได้รับการยอมรับ
- 204 ไม่มีเนื้อหา
- 400 คำขอไม่ถูกต้อง
- ไม่พบ 404
ตัวอย่างเช่นคุณเรียกใช้คำขอ GET users/9
แต่ไม่มีผู้ใช้ที่มี ID # 9 รหัสตอบกลับที่ดีที่สุดคืออะไร
คำตอบ:
TL; DR: ใช้ 404
ดูบล็อกนี้ มันอธิบายได้ดีมาก
สรุปความคิดเห็นของบล็อกใน204
:
204 No Content
ไม่มีประโยชน์อย่างยิ่งในฐานะรหัสการตอบสนองสำหรับเบราว์เซอร์ (แม้ว่าเบราว์เซอร์ตามข้อมูลจำเพาะ HTTP จะต้องเข้าใจว่าเป็นรหัสการตอบสนอง 'อย่าเปลี่ยนมุมมอง')204 No Content
เป็นแต่มีประโยชน์มากสำหรับการให้บริการเว็บ Ajax ซึ่งอาจต้องการที่จะแสดงให้เห็นความสำเร็จโดยไม่ต้องกลับบางสิ่งบางอย่าง (โดยเฉพาะอย่างยิ่งในกรณีเช่นDELETE
หรือPOST
ที่ไม่ต้องการความคิดเห็น)ดังนั้นคำตอบสำหรับคำถามของคุณคือใช้404
ในกรณีของคุณ เป็นรหัสที่ตอบสนองความที่คุณไม่ควรมักจะกลับมาที่เบราว์เซอร์ในการตอบสนองต่อ204
GET
รหัสตอบกลับอื่น ๆ ที่เหมาะสมน้อยกว่า204
และ404
:
200
ควรกลับมาพร้อมกับเนื้อหาของสิ่งที่คุณเรียกสำเร็จ ไม่เหมาะสมเมื่อไม่มีเอนทิตีที่คุณดึงข้อมูลอยู่202
ใช้เมื่อเซิร์ฟเวอร์เริ่มทำงานกับวัตถุ แต่วัตถุยังไม่พร้อม ไม่อย่างแน่นอนกรณีที่นี่ คุณยังไม่ได้เริ่มและจะไม่เริ่มสร้างผู้ใช้ 9 เพื่อตอบสนองต่อGET
คำขอ ที่ทำลายกฎทุกประเภท400
ถูกใช้เพื่อตอบสนองต่อคำขอ HTTP ที่จัดรูปแบบไม่ดี (ตัวอย่างเช่นส่วนหัว http ที่มีรูปแบบไม่ถูกต้องส่วนที่สั่งซื้อไม่ถูกต้อง ฯลฯ ) นี่จะเกือบถูกจัดการโดยกรอบสิ่งที่คุณใช้ คุณไม่ควรจัดการกับเรื่องนี้จนกว่าคุณจะเขียนเซิร์ฟเวอร์ของคุณเองตั้งแต่เริ่มต้น แก้ไข : RFC ที่ใหม่กว่าอนุญาตให้ใช้ 400 สำหรับคำขอที่ไม่ถูกต้องในเชิงความหมายคำอธิบายของรหัสสถานะ HTTPของ Wikipedia มีประโยชน์อย่างยิ่ง คุณสามารถดูคำจำกัดความในเอกสาร HTTP / 1.1 RFC2616 ได้ที่ www.w3.org
204
รหัสการตอบกลับ (ไม่มีเนื้อหา)
/badurl
หรือ/user/9
เมื่อไม่มีผู้ใช้ดังกล่าว นักพัฒนาสามารถช่วยด้วยการเพิ่มวลีเหตุผลที่ดีกว่า 'ไม่พบ' แต่ไม่จำเป็นต้อง
The server has not found anything matching the Request-URI
โดยเฉพาะ ในความเป็นจริงเว็บ / แอปพลิเคชันเซิร์ฟเวอร์พบ ACTION ที่ตรงกับ Request-URI แม้ว่าเซิร์ฟเวอร์ db จะไม่ อย่างไรก็ตามมันก็บอกว่าThis status code is commonly used when [...] no other response is applicable
ดังนั้นฉันคิดว่ามันตรวจสอบการใช้งานบ้าง (แม้ว่าฉันจะไม่เห็นด้วยกับ / ชอบมัน)
ฉันคัดค้าน 404 อย่างเห็นได้ชัด 204 หรือ 200 ด้วยข้อมูลว่างเปล่า หรืออย่างน้อยหนึ่งควรใช้เอนทิตีการตอบสนองกับ 404
ได้รับคำขอและประมวลผลอย่างถูกต้อง - มันเรียกรหัสแอปพลิเคชันบนเซิร์ฟเวอร์ดังนั้นจึงไม่สามารถพูดได้ว่าเป็นข้อผิดพลาดของไคลเอ็นต์และทำให้รหัสข้อผิดพลาดของไคลเอ็นต์ (4xx) ไม่เหมาะสม
ที่สำคัญกว่า 404 สามารถเกิดขึ้นได้ด้วยเหตุผลทางเทคนิคหลายประการ เช่นแอปพลิเคชั่นถูกปิดใช้งานชั่วคราวหรือถอนการติดตั้งบนเซิร์ฟเวอร์ปัญหาการเชื่อมต่อพร็อกซีและอะไรก็ตาม ดังนั้นไคลเอ็นต์ไม่สามารถแยกความแตกต่างระหว่าง 404 ที่หมายถึง "ชุดผลลัพธ์ที่ว่างเปล่า" และ 404 ที่หมายถึง "ไม่พบบริการลองอีกครั้งในภายหลัง"
สิ่งนี้อาจถึงแก่ชีวิตได้: ลองจินตนาการถึงบริการบัญชีใน บริษัท ของคุณที่มีรายชื่อพนักงานทุกคนที่ครบกำหนดโบนัสประจำปี โชคไม่ดีที่ครั้งหนึ่งมันถูกเรียกว่ามันจะส่งคืน 404 นั่นหมายความว่าไม่มีใครครบกำหนดโบนัสหรือว่าแอปพลิเคชันหยุดทำงานสำหรับการปรับใช้ใหม่หรือไม่?
-> สำหรับแอปพลิเคชันที่ใส่ใจกับคุณภาพของข้อมูล 404 ที่ไม่มีเอนทิตีการตอบสนอง
นอกจากนี้กรอบงานไคลเอนต์จำนวนมากตอบสนองต่อ 404 โดยการโยนข้อยกเว้นโดยไม่มีคำถามเพิ่มเติม สิ่งนี้บังคับให้นักพัฒนาไคลเอ็นต์จับข้อยกเว้นนั้นเพื่อประเมินและตัดสินใจโดยพิจารณาจากว่าจะบันทึกข้อผิดพลาดที่ถูกเลือกโดยเช่นองค์ประกอบการตรวจสอบหรือไม่สนใจ นั่นไม่ได้ดูสวยสำหรับฉันเช่นกัน
ข้อได้เปรียบของ 404 มากกว่า 204 คือสามารถส่งคืนเอนทิตีการตอบสนองที่อาจมีข้อมูลบางอย่างเกี่ยวกับสาเหตุที่ไม่พบทรัพยากรที่ร้องขอ แต่ถ้าสิ่งนั้นมีความเกี่ยวข้องจริง ๆ เราอาจพิจารณาใช้การตอบสนอง 200 OK และออกแบบระบบในลักษณะที่ช่วยให้สามารถตอบสนองข้อผิดพลาดในข้อมูลของข้อมูลที่บรรจุได้ อีกวิธีหนึ่งสามารถใช้ payload ของการตอบกลับ 404 เพื่อส่งคืนข้อมูลที่มีโครงสร้างให้กับผู้โทร หากเขาได้รับเช่นหน้า html แทน XML หรือ JSON ที่สามารถแยกวิเคราะห์ได้นั่นเป็นตัวบ่งชี้ที่ดีว่ามีบางอย่างผิดพลาดทางเทคนิคแทนที่จะตอบกลับ "ไม่มีผลลัพธ์" ที่อาจถูกต้องจากมุมมองของผู้โทร หรืออาจใช้ส่วนหัวการตอบสนอง HTTP สำหรับสิ่งนั้น
ยังฉันต้องการ 204 หรือ 200 กับการตอบสนองที่ว่างเปล่าว่า วิธีนั้นสถานะของการดำเนินการทางเทคนิคของคำขอจะถูกแยกออกจากผลลัพธ์ตรรกะของคำขอ 2xx หมายถึง "การดำเนินการทางเทคนิคตกลงนี่คือผลลัพธ์จัดการกับมัน"
ฉันคิดว่าในกรณีส่วนใหญ่ควรปล่อยให้ลูกค้าตัดสินใจว่าผลลัพธ์ว่างเปล่าเป็นที่ยอมรับหรือไม่ โดยการส่งคืน 404 โดยไม่มีเอนทิตีการตอบสนองแม้จะมีการดำเนินการทางเทคนิคที่ถูกต้องไคลเอนต์อาจตัดสินใจพิจารณากรณีเป็นข้อผิดพลาดที่ไม่มีข้อผิดพลาด
การเปรียบเทียบแบบด่วนอื่น: การส่งคืน 404 สำหรับ "ไม่พบผลลัพธ์" ก็เหมือนกับการโยน DatabaseConnectionException หากแบบสอบถาม SQL ไม่ส่งคืนผลลัพธ์ สามารถทำงานให้เสร็จได้ แต่มีสาเหตุทางเทคนิคมากมายที่อาจเกิดขึ้นได้ซึ่งมีข้อยกเว้นเดียวกันซึ่งจะทำให้เข้าใจผิดว่าเป็นผลลัพธ์ที่ถูกต้อง
503 Service Unavailable
คือ
/users
เส้นทาง แต่/users/9
คือ "ผู้ใช้ที่รู้จักกันในชื่อ # 9") ดังนั้นการเปรียบเทียบ 'ชุดผลลัพธ์ที่ว่างเปล่า' ของคุณจึงไม่สมเหตุสมผล 404 หมายความว่าวัตถุนั้นไม่มีอยู่จริง
ตอนแรกฉันคิดว่า 204 จะเข้าท่า แต่หลังจากการอภิปรายฉันเชื่อว่า 404 เป็นคำตอบที่ถูกต้องเท่านั้น พิจารณาข้อมูลต่อไปนี้:
ผู้ใช้: John, Peter
METHOD URL STATUS RESPONSE
GET /users 200 [John, Peter]
GET /users/john 200 John
GET /users/kyle 404 Not found
GET /users?name=kyle` 200 []
DELETE /users/john 204 No Content
พื้นหลังบางส่วน:
การค้นหาส่งคืนอาร์เรย์ แต่ไม่มีการจับคู่ใด ๆ แต่มีเนื้อหานั่นคืออาร์เรย์ว่าง
404 เป็นที่รู้จักกันดีที่สุดสำหรับ url ที่ไม่ได้รับการสนับสนุนจากเซิร์ฟเวอร์ที่ร้องขอ แต่แหล่งข้อมูลที่ขาดหายไปนั้นเหมือนกัน
แม้ว่า/users/:name
จะจับคู่กับusers/kyle
ผู้ใช้ Kyle ผู้ใช้ไม่สามารถใช้ทรัพยากรดังนั้น 404 ยังคงใช้ มันไม่ใช่ข้อความค้นหา แต่เป็นการอ้างอิงโดยตรงจาก URL แบบไดนามิกดังนั้นจึงเป็น 404
อย่างไรก็ตามสองเซ็นต์ของฉัน :)
หากคาดว่ามีทรัพยากรอยู่ แต่อาจว่างเปล่าฉันจะโต้แย้งว่ามันอาจจะง่ายกว่าที่จะได้ 200 OK ด้วยการเป็นตัวแทนที่บ่งบอกว่าสิ่งนั้นว่างเปล่า
ดังนั้นฉันจึงอยากได้ / สิ่งต่าง ๆ คืนค่า 200 OK ด้วย {"รายการ": []} มากกว่า 204 ที่ไม่มีอะไรเลยเพราะด้วยวิธีนี้คอลเลคชันที่มี 0 รายการสามารถถือว่าเหมือนกับคอลเลกชันที่มีหนึ่งหรือ รายการเพิ่มเติมในนั้น
ฉันเพิ่งปล่อย 204 ไม่มีเนื้อหาสำหรับ PUTs และ DELETEs ซึ่งอาจเป็นกรณีที่ไม่มีการนำเสนอที่เป็นประโยชน์จริง ๆ
ในกรณีที่ไม่มีสิ่ง / / 9 จริงๆ 404 นั้นเหมาะสม
customers/1/addressbook
วิธี RPC คือการเรียกจุดสิ้นสุดเช่นGetCustomerAddressBook
และรับข้อมูลหรือเป็นโมฆะเป็นหลักและไม่ต้องกังวลเกี่ยวกับความซับซ้อนของ HTTP มีทั้งข้อดีและข้อเสีย
ในโครงการก่อนหน้านี้ฉันใช้ 404 หากไม่มีผู้ใช้ 9 แสดงว่าไม่พบวัตถุ ดังนั้น 404 ไม่พบมีความเหมาะสม
สำหรับวัตถุที่มีอยู่ แต่ไม่มีข้อมูล 204 ไม่มีเนื้อหาจะเหมาะสม ผมคิดว่าในกรณีของวัตถุที่ไม่ได้อยู่แม้ว่า
ตามที่w3โพสต์
200 ตกลง
การร้องขอสำเร็จแล้ว ข้อมูลที่ส่งคืนพร้อมการตอบกลับจะขึ้นอยู่กับวิธีที่ใช้ในคำขอ
202 ได้รับการยอมรับ
คำขอได้รับการยอมรับสำหรับการประมวลผล แต่การประมวลผลยังไม่เสร็จสมบูรณ์
204 ไม่มีเนื้อหา
เซิร์ฟเวอร์ดำเนินการตามคำขอ แต่ไม่จำเป็นต้องส่งคืนเอนทิตีและอาจต้องการส่งคืนข้อมูลปรับปรุงที่อัปเดต
400 คำขอไม่ถูกต้อง
เซิร์ฟเวอร์ไม่สามารถเข้าใจการร้องขอได้เนื่องจากไวยากรณ์ผิดรูปแบบ ลูกค้าไม่ควรทำซ้ำการร้องขอโดยไม่มีการดัดแปลง
401 ไม่ได้รับอนุญาต
การร้องขอต้องมีการรับรองความถูกต้องของผู้ใช้ การตอบสนองต้องมีฟิลด์ส่วนหัว WWW-Authenticate
ไม่พบ 404
เซิร์ฟเวอร์ไม่พบสิ่งใดที่ตรงกับ Request-URI ไม่มีการบ่งชี้ว่าเงื่อนไขเป็นแบบชั่วคราวหรือถาวร
204 No Content
เมื่อไม่มีผลลัพธ์ ไม่ได้404
ก็มีผลสำหรับคุณ แต่มันไม่มีเนื้อหา ..
เพื่อสรุปหรือทำให้ง่ายขึ้น
2xx: ข้อมูลเพิ่มเติม: รูปแบบที่ดี URI: เกณฑ์ไม่ได้เป็นส่วนหนึ่งของ URI: หากเกณฑ์เป็นตัวเลือกที่สามารถระบุได้ใน @RequestBody และ @RequestParam ควรนำไปสู่ 2xx ตัวอย่าง: กรองตามชื่อ / สถานะ
4xx: ข้อมูลที่คาดหวัง: รูปแบบที่ไม่ดี URI: เกณฑ์เป็นส่วนหนึ่งของ URI: หากเกณฑ์เป็นข้อบังคับที่สามารถระบุได้เฉพาะใน @PathVariable เท่านั้นจึงควรนำไปสู่ 4xx ตัวอย่าง: ค้นหาด้วย id เฉพาะ
ดังนั้นสำหรับสถานการณ์ที่ถาม: "users / 9" จะเป็น 4xx (อาจเป็น 404) แต่สำหรับ "users? name = superman" ควรเป็น 2xx (อาจเป็น 204)
มีคำถามสองข้อถาม หนึ่งในชื่อและอีกหนึ่งในตัวอย่าง ฉันคิดว่านี่เป็นส่วนหนึ่งที่นำไปสู่จำนวนข้อพิพาทเกี่ยวกับการตอบสนองที่เหมาะสม
ชื่อคำถามถามเกี่ยวกับข้อมูลที่ว่างเปล่า ข้อมูลที่ว่างเปล่ายังคงเป็นข้อมูล แต่ไม่เหมือนกันกับไม่มีข้อมูล ดังนั้นสิ่งนี้แนะนำให้ขอชุดผลลัพธ์เช่นรายการบางทีจาก/users
ดังนั้นนี้แสดงให้เห็นขอชุดผลลัพธ์คือรายการอาจจากหากรายการว่างเปล่ามันยังคงเป็นรายการดังนั้น 204 (ไม่มีเนื้อหา) จึงเหมาะสมที่สุด คุณเพิ่งขอรายชื่อผู้ใช้และได้รับรายชื่อหนึ่งรายการมันเกิดขึ้นเมื่อไม่มีเนื้อหา
ตัวอย่างที่ให้มาถามเกี่ยวกับวัตถุเฉพาะผู้ใช้ /users/9
ตัวอย่างที่ให้ไว้แทนถามเกี่ยวกับวัตถุที่เฉพาะเจาะจงที่ผู้ใช้หากไม่พบผู้ใช้ # 9 จะไม่มีการส่งคืนวัตถุผู้ใช้ คุณขอทรัพยากรเฉพาะ (วัตถุผู้ใช้) และไม่ได้รับเพราะไม่พบดังนั้น 404 จึงเหมาะสม
ฉันคิดว่าวิธีการแก้ไขปัญหานี้คือถ้าคุณสามารถใช้การตอบสนองในแบบที่คุณคาดหวังได้โดยไม่ต้องเพิ่มคำสั่งแบบมีเงื่อนไขใด ๆ จากนั้นใช้ 204 หรือใช้ 404
ในตัวอย่างของฉันฉันสามารถวนซ้ำรายการที่ว่างโดยไม่ตรวจสอบเพื่อดูว่ามีเนื้อหาหรือไม่ แต่ฉันไม่สามารถแสดงข้อมูลวัตถุผู้ใช้บนวัตถุว่างเปล่าโดยไม่ทำลายหรือเพิ่มการตรวจสอบเพื่อดูว่ามันเป็นโมฆะ
แน่นอนคุณสามารถส่งคืนวัตถุโดยใช้รูปแบบวัตถุ null หากที่เหมาะสมกับความต้องการของคุณ แต่นั่นคือการสนทนาสำหรับหัวข้ออื่น
หลังจากดูคำถามคุณไม่ควรใช้404
ทำไม
ขึ้นอยู่กับRFC 7231รหัสสถานะที่ถูกต้องคือ204
ในแอปพลิเคชันด้านบนฉันสังเกตเห็นความเข้าใจผิดเล็กน้อย 1 ข้อ
1.- ทรัพยากรคือ: /users
2.- /users/8
ไม่ใช่ทรัพยากรนี่คือ: ทรัพยากรที่/users
มีพารามิเตอร์เส้นทาง8
ผู้บริโภคอาจไม่สามารถสังเกตเห็นได้และไม่ทราบความแตกต่าง แต่ผู้เผยแพร่ทำและต้องรู้สิ่งนี้! ... ดังนั้นเขาจะต้องตอบสนองผู้บริโภคอย่างแม่นยำ ระยะเวลา
ดังนั้น:
จาก RFC: 404 ไม่ถูกต้องเนื่องจาก/users
พบทรัพยากรแต่ลอจิกที่ดำเนินการโดยใช้พารามิเตอร์8
ไม่พบสิ่งใดที่content
จะส่งกลับเป็นการตอบสนองดังนั้นคำตอบที่ถูกต้องคือ:204
ประเด็นหลักที่นี่คือ: 404
ไม่พบว่ามีทรัพยากรในการประมวลผลตรรกะภายใน
204
คือ: ฉันพบทรัพยากรตรรกะถูกดำเนินการ แต่ฉันไม่พบข้อมูลใด ๆ โดยใช้เกณฑ์ของคุณที่ระบุไว้ในพารามิเตอร์เส้นทางดังนั้นฉันไม่สามารถคืนสิ่งใดให้คุณ ขออภัยตรวจสอบเกณฑ์ของคุณและโทรหาฉันอีกครั้ง
200
: ตกลงฉันพบทรัพยากรตรรกะถูกดำเนินการ (แม้เมื่อฉันไม่ได้บังคับให้คืนสิ่งใด) ใช้สิ่งนี้และใช้ตามความประสงค์ของคุณ
205
: (ตัวเลือกที่ดีที่สุดของการตอบกลับ GET) ฉันพบทรัพยากรตรรกะถูกดำเนินการฉันมีเนื้อหาบางส่วนสำหรับคุณใช้งานได้ดีด้วยวิธีที่คุณจะแบ่งปันสิ่งนี้ในมุมมองโปรดรีเฟรชมุมมองเพื่อ แสดงมัน
หวังว่ามันจะช่วย
สิ่งที่คำตอบที่มีอยู่ไม่ได้ทำอย่างละเอียดคือมันสร้างความแตกต่างไม่ว่าคุณจะใช้พารามิเตอร์พา ธ หรือพารามิเตอร์เคียวรี
/users/9
การตอบสนองควรเป็น404
เพราะไม่พบทรัพยากรนั้น /users/9
เป็นทรัพยากรและผลลัพธ์นั้นเป็นข้อผิดพลาดหรือไม่มีข้อผิดพลาด นี่ไม่ใช่ Monad/users?id=9
การตอบสนองควรเป็น204
เพราะ/users
พบทรัพยากรแต่ไม่สามารถส่งคืนข้อมูลใด ๆ มีทรัพยากร/users
อยู่และผลลัพธ์เป็นค่าที่ไม่ถูกต้องแม้ว่าจะว่างเปล่าก็ตาม ถ้าid
เป็นเอกลักษณ์นี่คือ monadว่าจะใช้พารามิเตอร์พา ธ หรือพารามิเตอร์เคียวรีขึ้นอยู่กับกรณีการใช้งาน ฉันชอบพารามิเตอร์พา ธ สำหรับคำสั่งบังคับ, กฎเกณฑ์, หรือการระบุอาร์กิวเมนต์และพารามิเตอร์การสืบค้นสำหรับอาร์กิวเมนต์ที่เป็นทางเลือก, ไม่เป็นบรรทัดฐาน, หรือการอ้างเหตุผล (เช่นเพจจิ้ง, การเรียงหน้าภาษา ใน REST API ผมจะใช้/users/9
ไม่ได้/users?id=9
โดยเฉพาะอย่างยิ่งเพราะการทำรังที่เป็นไปได้ที่จะได้รับ "บันทึกเด็ก" ชอบ/users/9/ssh-keys/0
ที่จะได้รับคีย์สาธารณะ SSH ครั้งแรกหรือครั้ง/users/9/address/2
ที่จะได้รับที่อยู่ทางไปรษณีย์สาม
ฉันชอบใช้ 404 นี่คือเหตุผล:
204
เป็นเหมือนvoid
วิธีการ ฉันจะไม่ใช้มันGET
เพียงเพื่อPOST
, และPUT
DELETE
ฉันสร้างข้อยกเว้นในกรณีGET
ที่ตัวระบุเป็นพารามิเตอร์การสืบค้นไม่ใช่พารามิเตอร์พา ธNoSuchElementException
นั้นArrayIndexOutOfBoundsException
หรือสิ่งที่เกิดขึ้นจากลูกค้าโดยใช้รหัสที่ไม่มีอยู่ดังนั้นจึงเป็นข้อผิดพลาดของไคลเอ็นต์204
หมายถึงสาขาเพิ่มเติมในรหัสที่สามารถหลีกเลี่ยงได้ มันซับซ้อนรหัสลูกค้าและในบางกรณีก็มีความซับซ้อนรหัสเซิร์ฟเวอร์ (ขึ้นอยู่กับว่าคุณใช้เอนทิตี้ / แบบจำลอง monads หรือเอนทิตี / รุ่นธรรมดาและฉันขอแนะนำให้อยู่ห่างจากเอนทิตี้ / แบบจำลอง monads มันอาจนำไปสู่ ของ monad ที่คุณคิดว่าการผ่าตัดประสบความสำเร็จและคืน 200 หรือ 204 เมื่อคุณควรส่งคืนอย่างอื่น)สุดท้าย แต่ไม่ท้ายสุด: ความสอดคล้อง
GET /users/9
PUT /users/9
และ DELETE /users/9
PUT /users/9
และDELETE /users/9
ต้องกลับมา204
ในกรณีที่การอัปเดตหรือลบสำเร็จ ดังนั้นสิ่งที่พวกเขาควรกลับมาในกรณีที่ผู้ใช้ 9 ไม่มีอยู่? มันไม่มีเหตุผลที่จะมีสถานการณ์เดียวกับที่แสดงเป็นรหัสสถานะที่แตกต่างกันขึ้นอยู่กับวิธีการใช้ HTTP
นอกจากนี้ไม่ใช่กฎเกณฑ์ แต่เป็นเหตุผลทางวัฒนธรรม: หาก204
ใช้เพื่อGET /users/9
สิ่งต่อไปที่จะเกิดขึ้นในโครงการคือมีใครบางคนคิดว่าการกลับมา204
เป็นสิ่งที่ดีสำหรับวิธีการแบบดั้งเดิม และนั่นทำให้รหัสลูกค้าซับซ้อนเพราะแทนที่จะตรวจสอบ2xx
แล้วถอดรหัสร่างกายลูกค้าต้องทำการตรวจสอบโดยเฉพาะ204
และในกรณีนั้นข้ามการถอดรหัสเนื้อหา แตกหน่อลูกค้าทำอะไรแทน สร้างอาร์เรย์ว่างหรือไม่ ทำไมไม่มีเส้นลวดล่ะ? หากลูกค้าสร้างอาร์เรย์ที่ว่างเปล่า 204 เป็นรูปแบบของการบีบอัดโง่ หากไคลเอนต์ใช้null
แทนจะสามารถเปิดเวิร์มต่าง ๆ ได้
Twitter ใช้ 404 พร้อมข้อความแสดงข้อผิดพลาดที่กำหนดเองเช่น "ไม่พบข้อมูล"
Ref: https://developer.twitter.com/en/docs/basics/response-codes.html
204 เหมาะสมกว่า โดยเฉพาะอย่างยิ่งเมื่อคุณมีระบบการแจ้งเตือนเพื่อให้แน่ใจว่าเว็บไซต์ของคุณปลอดภัย 404 ในกรณีนี้จะทำให้เกิดความสับสนเพราะคุณไม่รู้ว่าการแจ้งเตือน 404 นั้นเป็นข้อผิดพลาดแบ็กเอนด์หรือคำขอปกติ แต่ไม่มีการตอบสนอง
ฉันจะบอกว่าไม่เหมาะสมจริงๆ ดังที่ได้กล่าวไว้ - โดย @anneb ฉันก็คิดว่าปัญหาส่วนหนึ่งเกิดจากการใช้รหัสตอบกลับ HTTP เพื่อส่งสถานะที่เกี่ยวข้องกับบริการ RESTful สิ่งใดที่บริการ REST ต้องกล่าวเกี่ยวกับการดำเนินการของตนเองควรได้รับการขนส่งโดยใช้รหัสเฉพาะของ REST
ฉันขอยืนยันว่าหากเซิร์ฟเวอร์ HTTP พบบริการใด ๆ ที่พร้อมที่จะตอบคำขอที่ถูกส่งไปมันไม่ควรตอบกลับด้วย HTTP 404 - ในที่สุดเซิร์ฟเวอร์จะพบบางสิ่ง - เว้นแต่จะมีการบอกอย่างชัดเจนจาก บริการที่ประมวลผลคำขอ
สมมติว่าสำหรับช่วงเวลาที่ URL http://example.com/service/return/test
ต่อไปนี้:
404
ถูกต้อง เช่นเดียวกันถ้ามันขอให้บริการบางอย่างส่งไฟล์นี้อย่างแน่นอนและบริการนั้นบอกว่าไม่มีชื่อนั้นอยู่หากไม่มีการตอบสนองใด ๆ จากบริการที่ต้องการพฤติกรรมที่แตกต่างอย่างชัดเจนเซิร์ฟเวอร์ HTTP สามารถพูดได้ 3 สิ่งเท่านั้น:
503
ถ้าบริการที่ควรจะจัดการกับคำขอไม่ได้ทำงานหรือตอบสนอง;200
มิฉะนั้นเป็นเซิร์ฟเวอร์ HTTP สามารถตอบสนองคำขอได้จริง - ไม่ว่าบริการจะพูดอะไรในภายหลัง400
หรือ404
เพื่อระบุว่าไม่มีบริการดังกล่าว (ตรงข้ามกับ "มีอยู่ แต่ออฟไลน์") และไม่พบสิ่งใดเมื่อต้องการกลับไปที่คำถามที่อยู่: ฉันคิดว่าวิธีการที่สะอาดที่สุดจะไม่ใช้รหัสการตอบสนองใด ๆ เลยนอกจากที่กล่าวมาก่อนหน้านี้ หากบริการมีอยู่และตอบสนองรหัส HTTP ควรเป็น 200 การตอบสนองควรมีสถานะที่บริการส่งคืนในส่วนหัวแยกต่างหาก - ที่นี่บริการสามารถพูดได้
REST:EMPTY
เช่นถ้าถูกขอให้ค้นหา sth และงานวิจัยนั้นกลับว่างเปล่าREST:NOT FOUND
ถ้ามันถูกถามโดยเฉพาะสำหรับฏ. “ เหมือน ID” - เป็นชื่อไฟล์หรือทรัพยากรตาม ID หรือรายการหมายเลข 24 เป็นต้น - และไม่พบทรัพยากรที่ระบุ (โดยปกติจะมีการขอทรัพยากรเฉพาะหนึ่งรายการและไม่พบ)REST:INVALID
หากส่วนใดส่วนหนึ่งของคำขอที่ส่งไปนั้นไม่ได้รับการยอมรับจากบริการ(โปรดทราบว่าฉันนำหน้าสิ่งเหล่านี้ด้วย“ REST:” โดยมีวัตถุประสงค์เพื่อทำเครื่องหมายข้อเท็จจริงว่าแม้ว่าสิ่งเหล่านี้อาจมีค่าหรือถ้อยคำเดียวกันกับรหัสการตอบกลับ HTTP แต่พวกเขาแตกต่างกันโดยสิ้นเชิง)
กลับไปที่ URL ข้างต้นแล้วตรวจสอบกรณี B ที่ให้บริการบ่งชี้ไปยังเซิร์ฟเวอร์ HTTP ที่มันไม่ได้จัดการกับคำขอนี้เอง SERVICE
แต่ผ่านมันไป HTTP เพียงทำหน้าที่ออกว่ามันจะกลับมามือโดยSERVICE
ก็ไม่ได้รู้อะไรเกี่ยวกับreturn/test
ส่วนที่เป็นที่ handeled SERVICE
โดย หากบริการนั้นกำลังทำงานอยู่ HTTP ควรกลับมา200
เหมือนเดิมเมื่อพบบางสิ่งเพื่อจัดการกับคำขอ
สถานะที่ส่งคืนโดยSERVICE
(และซึ่งตามที่กล่าวไว้ข้างต้นต้องการเห็นในส่วนหัวที่แยกต่างหาก) ขึ้นอยู่กับการกระทำที่คาดหวังจริง:
return/test
ถามถึงทรัพยากรที่เฉพาะเจาะจง: ถ้ามีอยู่ให้ส่งคืนด้วยสถานะของREST:FOUND
; ถ้าทรัพยากรที่ไม่อยู่กลับREST:NOT FOUND
; สิ่งนี้สามารถขยายออกเพื่อส่งคืนREST:GONE
ถ้าเรารู้ว่ามีอยู่ครั้งเดียวและจะไม่กลับมาและREST:MOVED
ถ้าเรารู้ว่ามันหายไปจากฮอลลีวู้ดreturn/test
พิจารณาว่าเป็นการดำเนินการค้นหาหรือคล้ายตัวกรอง: หากชุดผลลัพธ์ว่างเปล่าให้ส่งคืนชุดว่างในประเภทที่ร้องขอและสถานะเป็นREST:EMPTY
; ชุดผลลัพธ์ในประเภทที่ร้องขอและสถานะเป็นREST:SUCCESS
return/test
ไม่ใช่การปฏิบัติการที่คำนวณโดยSERVICE
: return REST:ERROR
ถ้ามันผิดทั้งหมด (เช่น typo like retrun/test
) หรือREST:NOT IMPLEMENTED
ในกรณีที่มีการวางแผนในภายหลังความแตกต่างนี้สะอาดกว่าการผสมสองอย่างเข้าด้วยกัน นอกจากนี้ยังจะทำให้การดีบักง่ายขึ้นและประมวลผลเพียงเล็กน้อยที่ซับซ้อนมากขึ้นถ้าทั้งหมด
ปัญหาและการสนทนาเกิดขึ้นจากความจริงที่ว่ามีการใช้รหัสการตอบสนอง HTTP เพื่อแสดงสถานะของบริการที่มีการให้บริการผลลัพธ์โดย HTTP หรือเพื่อแสดงถึง sth ที่ไม่ได้อยู่ในขอบเขตของเซิร์ฟเวอร์ HTTP นั้นเอง เนื่องจากความคลาดเคลื่อนนี้คำถามจึงไม่สามารถตอบได้และความคิดเห็นทั้งหมดอาจมีการอภิปรายจำนวนมาก
สถานะของคำร้องขอที่ประมวลผลโดยเซอร์วิสและไม่ใช่เซิร์ฟเวอร์ HTTP ควรได้รับจริงๆ (RFC 6919) โดยรหัสตอบกลับ HTTP รหัส HTTP SHOULD (RFC 2119) มีเฉพาะข้อมูลที่เซิร์ฟเวอร์ HTTP สามารถให้จากขอบเขตของตัวเอง: กล่าวคือไม่ว่าจะพบบริการที่จะดำเนินการตามคำขอหรือไม่
แทนที่จะใช้วิธีอื่นควรใช้เพื่อบอกผู้บริโภคเกี่ยวกับสถานะของคำขอไปยังบริการที่กำลังประมวลผลคำขอ ข้อเสนอของฉันคือการทำผ่านส่วนหัวที่เฉพาะเจาะจง ตามหลักการแล้วชื่อของส่วนหัวและเนื้อหาจะเป็นไปตามมาตรฐานที่ทำให้ผู้บริโภคสามารถทำงานกับการตอบสนองเหล่านี้ได้ง่าย
ตาม RFC7231 - page59 ( https://tools.ietf.org/html/rfc7231#page-59 ) คำจำกัดความของการตอบสนองรหัสสถานะ 404 คือ:
6.5.4 404 ไม่พบรหัสสถานะ 404 (ไม่พบ) ระบุว่าเซิร์ฟเวอร์ต้นทางไม่พบการแสดงปัจจุบันสำหรับทรัพยากรเป้าหมายหรือไม่เต็มใจที่จะเปิดเผยว่ามีอยู่ รหัสสถานะ 404 ไม่ได้ระบุว่าการขาดการเป็นตัวแทนนี้เป็นการชั่วคราวหรือถาวร รหัสสถานะ 410 (หายไป) เป็นที่ต้องการมากกว่า 404 ถ้าเซิร์ฟเวอร์ต้นทางรู้ว่าน่าจะเป็นวิธีที่สามารถกำหนดค่าได้ซึ่งน่าจะเป็นเงื่อนไขที่ถาวร การตอบกลับ 404 สามารถแคชได้โดยค่าเริ่มต้น เช่นเว้นแต่ระบุไว้เป็นอย่างอื่นโดยคำนิยามวิธีการหรือการควบคุมแคชอย่างชัดเจน (ดูหัวข้อ 4.2.2 ของ [RFC7234])
และสิ่งสำคัญที่ทำให้เกิดความสงสัยคือนิยามของทรัพยากรในบริบทข้างต้น ตาม RFC เดียวกัน (7231) คำจำกัดความของทรัพยากรคือ:
ทรัพยากร: เป้าหมายของคำขอ HTTP เรียกว่า "ทรัพยากร" HTTP ไม่ได้ จำกัด ลักษณะของทรัพยากร เพียงกำหนดอินเทอร์เฟซที่อาจใช้เพื่อโต้ตอบกับทรัพยากร แต่ละทรัพยากรถูกระบุโดย Uniform Resource Identifier (URI) ตามที่อธิบายไว้ในส่วนที่ 2.7 ของ [RFC7230] เมื่อลูกค้าสร้างข้อความร้องขอ HTTP / 1.1 ลูกค้าจะส่ง URI เป้าหมายในรูปแบบต่าง ๆ ตามที่กำหนดไว้ใน (ส่วน 5.3 ของ [RFC7230] เมื่อได้รับคำขอเซิร์ฟเวอร์จะสร้าง URI คำขอที่มีประสิทธิภาพใหม่สำหรับทรัพยากรเป้าหมาย (มาตรา 5.5 ของ [RFC7230]) เป้าหมายการออกแบบหนึ่งของ HTTP คือการแยกการระบุทรัพยากรจากซีแมนทิกส์คำขอซึ่งทำไปได้โดยการมอบซีเมนต์คำขอในวิธีการร้องขอ (ส่วนที่ 4) และฟิลด์ส่วนหัวที่ปรับเปลี่ยนการร้องขอไม่กี่ (ส่วนที่ 5)
ดังนั้นในรหัสสถานะ 404 ของฉันไม่ควรใช้กับคำขอ GET ที่ประสบความสำเร็จกับผลลัพธ์ที่ว่างเปล่า (ตัวอย่าง: รายการที่ไม่มีผลลัพธ์สำหรับตัวกรองเฉพาะ)
สิ่งต่าง ๆ เหล่านี้อาจเป็นอัตนัยและมีข้อโต้แย้งที่น่าสนใจและหลากหลายทั้งสองด้าน อย่างไรก็ตาม [ในความคิดของฉัน] กลับ 404 สำหรับข้อมูลที่ขาดหายไปไม่ถูกต้อง ต่อไปนี้เป็นคำอธิบายที่เข้าใจง่ายเพื่อให้ชัดเจน:
ไม่พบจุดสิ้นสุดและพบตารางและคอลัมน์เพื่อให้ DB สอบถามและข้อมูลถูกส่งคืน "สำเร็จ"!
ตอนนี้ - ไม่ว่า "การตอบสนองที่ประสบความสำเร็จ" มีข้อมูลหรือไม่ไม่สำคัญคุณขอการตอบสนองของข้อมูล "ที่มีศักยภาพ" และการตอบสนองที่มีข้อมูล "ที่อาจเกิดขึ้น" นั้น ว่างเปล่า ฯลฯ เป็นข้อมูลที่ถูกต้อง
200 หมายถึงการร้องขออะไรก็ตามที่เราประสบความสำเร็จ ฉันขอข้อมูลไม่มีข้อผิดพลาดกับ HTTP / REST และเนื่องจากข้อมูล (แม้ว่าจะว่างเปล่า) ก็ถูกส่งคืน "คำขอข้อมูล" ของฉันสำเร็จ
ส่งคืน 200 และปล่อยให้ผู้ร้องขอจัดการข้อมูลที่ว่างเปล่าเนื่องจากแต่ละสถานการณ์สมมติรับประกัน!
ลองพิจารณาตัวอย่างนี้:
ข้อมูลนี้ว่างเปล่าถูกต้องทั้งหมด หมายความว่าผู้ใช้ไม่มีการละเมิด นี่คือ 200 เนื่องจากใช้ได้ทั้งหมดแล้วฉันสามารถทำ:
คุณไม่มีการละเมิดมีมัฟฟินบลูเบอร์รี่!
หากคุณเห็นว่านี่คือ 404 คุณจะระบุอะไร ไม่พบการละเมิดของผู้ใช้ ตอนนี้ทางไวยากรณ์ที่ถูกต้อง แต่ก็ไม่ถูกต้องในโลกที่เหลือเป็นความสำเร็จหรือความล้มเหลวเป็นเรื่องเกี่ยวกับการร้องขอ สามารถค้นหาข้อมูล "การละเมิด" สำหรับผู้ใช้รายนี้ได้อย่างประสบความสำเร็จโดยไม่มีการละเมิดศูนย์ - จำนวนจริงที่แสดงถึงสถานะที่ถูกต้อง
[โน้ตหน้าด้าน .. ]
ในชื่อของคุณคุณยอมรับโดยไม่รู้ตัวว่า 200 เป็นการตอบสนองที่ถูกต้อง:
รหัสตอบกลับ REST ที่เหมาะสมสำหรับคำขอที่ถูกต้องแต่เป็นข้อมูลว่างเปล่าคืออะไร
ต่อไปนี้เป็นสิ่งที่ควรพิจารณาเมื่อเลือกรหัสสถานะที่จะใช้
เข้ารหัสเนื้อหาการตอบกลับด้วย enum ทั่วไปที่อนุญาตให้ไคลเอ็นต์เปิดใช้งานและแยกลอจิกตามลำดับ ฉันไม่แน่ใจว่าลูกค้าของคุณจะแยกความแตกต่างระหว่าง "data not found" 404 และ "ไม่พบทรัพยากรเว็บ" 404 ได้อย่างไร คุณไม่ต้องการให้ใครบางคนเรียกดูผู้ใช้Z / 9 และให้ลูกค้าสงสัยว่าคำขอนั้นถูกต้อง แต่ไม่มีข้อมูลที่ส่งคืน
ทำไมไม่ใช้ 410? มันแนะนำทรัพยากรที่ร้องขอไม่มีอยู่อีกต่อไปและลูกค้าคาดว่าจะไม่ทำการร้องขอทรัพยากรนั้นในกรณีของคุณusers/9
มันแสดงให้เห็นทรัพยากรที่ร้องขอไม่มีอยู่แล้วและลูกค้าที่คาดว่าจะไม่ทำตามคำขอสำหรับทรัพยากรนั้นในกรณีของคุณ
คุณสามารถค้นหารายละเอียดเพิ่มเติมเกี่ยวกับ 410 ได้ที่นี่: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
มันเป็นเรื่องน่าเศร้าที่บางสิ่งที่เรียบง่ายและมีความหมายได้กลายมาเป็น "ฐานความคิดเห็น" ในหัวข้อนี้
เซิร์ฟเวอร์ HTTP รู้เพียง "เอนทิตี" ซึ่งเป็นนามธรรมสำหรับเนื้อหาใด ๆ ไม่ว่าจะเป็นหน้าเว็บแบบสแตติกรายการผลการค้นหารายชื่อเอนทิตีอื่น ๆ คำอธิบาย json ของบางสิ่งบางอย่างไฟล์สื่อ ฯลฯ
แต่ละเอนทิตีดังกล่าวคาดว่าจะสามารถระบุได้โดย URL ที่ไม่ซ้ำกันเช่น
หากเซิร์ฟเวอร์ค้นหาทรัพยากรด้วย URL ที่กำหนดมันไม่สำคัญว่าเนื้อหาของมันคืออะไร - 2G ของข้อมูล, null, {}, [] - ตราบใดที่มีอยู่มันจะเป็น 200 แต่ถ้าเอนทิตีดังกล่าวเป็น ไม่รู้จักเซิร์ฟเวอร์เป็น EXPECTED ที่จะส่งคืน 404 "ไม่พบ"
ความสับสนหนึ่งดูเหมือนว่ามาจากนักพัฒนาที่คิดว่าหากแอปพลิเคชันมีตัวจัดการสำหรับรูปร่างเส้นทางที่แน่นอนมันไม่ควรเป็นข้อผิดพลาด ในสายตาของโปรโตคอล HTTP มันไม่สำคัญว่าเกิดอะไรขึ้นใน internals ของเซิร์ฟเวอร์ (เช่นไม่ว่าจะเป็นเราเตอร์เริ่มต้นตอบสนองหรือจัดการสำหรับรูปร่างเส้นทางที่เฉพาะเจาะจง) ตราบใดที่ไม่มีเอนทิตีที่ตรงกันบนเซิร์ฟเวอร์ไปยัง URL ที่ร้องขอ (ที่ร้องขอไฟล์ MP3 หน้าเว็บวัตถุผู้ใช้ ฯลฯ ) ซึ่งจะส่งคืนเนื้อหาที่ถูกต้อง (ว่างเปล่าหรืออย่างอื่น) จะต้องเป็น 404 (หรือ 410 เป็นต้น)
อีกประเด็นที่น่าสับสนก็คือ "ไม่มีข้อมูล" และ "ไม่มีเอนทิตี" อดีตคือเนื้อหาของเอนทิตีและสิ่งหลังเกี่ยวกับการมีอยู่ของมัน
ตัวอย่างที่ 1:
ตัวอย่างที่ 2:
ตัวอย่างที่ 3:
404 จะสร้างความสับสนให้กับลูกค้าหากคุณกลับมาเพราะไม่มีข้อมูลในการตอบสนอง
สำหรับฉันรหัสตอบสนอง 200 ที่มีร่างกายว่างเปล่าเพียงพอที่จะเข้าใจว่าทุกอย่างสมบูรณ์แบบ แต่ไม่มีข้อมูลที่ตรงกับข้อกำหนด
ตามที่ Microsoft: ตัวควบคุมชนิดส่งคืนการกระทำใน ASP.NET Core API เว็บเลื่อนลงไปด้านล่างเกือบคุณพบ blurb ต่อไปนี้เกี่ยวกับ 404 ที่เกี่ยวข้องกับวัตถุที่ไม่พบในฐานข้อมูล ที่นี่พวกเขาแนะนำว่า 404 เหมาะสำหรับข้อมูลที่ว่างเปล่า
ตามที่ระบุไว้โดยส่วนใหญ่ 404 นั้นทำให้เข้าใจผิดและไม่อนุญาตให้ลูกค้าแยกแยะหากคำขอ uri ไม่มีอยู่หรือถ้า uri ที่ร้องขอไม่สามารถดึงทรัพยากรที่ร้องขอได้
คาดว่าสถานะ 200 จะมีข้อมูลทรัพยากร - ดังนั้นจึงไม่ใช่ตัวเลือกที่เหมาะสม สถานะ 204 หมายถึงอย่างอื่นทั้งหมดและไม่ควรใช้เป็นการตอบกลับคำขอ GET
สถานะที่มีอยู่อื่นทั้งหมดไม่สามารถใช้ได้ด้วยเหตุผลใดเหตุผลหนึ่งหรืออย่างอื่น
ฉันได้เห็นหัวข้อนี้ถูกกล่าวถึงครั้งแล้วครั้งเล่าในหลายสถานที่ สำหรับฉันมันชัดเจนว่าการกำจัดความสับสนในหัวข้อนั้นจำเป็นต้องมีสถานะความสำเร็จเฉพาะ บางอย่างเช่น " 209 - ไม่มีทรัพยากรที่จะแสดง"
มันจะเป็นสถานะ 2xx เนื่องจากการไม่พบ ID ไม่ควรพิจารณาว่าเป็นข้อผิดพลาดของไคลเอ็นต์ (หากลูกค้ารู้ทุกอย่างที่อยู่ในฐานข้อมูลของเซิร์ฟเวอร์พวกเขาไม่จำเป็นต้องถามอะไรกับเซิร์ฟเวอร์เลยใช่ไหม) สถานะเฉพาะนี้จะแก้ไขปัญหาทั้งหมดที่ถกเถียงด้วยการใช้สถานะอื่น
คำถามเดียวก็คือ: ฉันจะให้ RFC ยอมรับว่าเป็นมาตรฐานได้อย่างไร