ฉันควรส่งคืนการตอบสนอง 204 หรือ 404 เมื่อไม่พบทรัพยากรหรือไม่


15

ฉันกำลังพัฒนาบริการ RESTful ที่เรียบง่ายสำหรับทัวร์นาเมนต์และกำหนดเวลา เมื่อมีการสร้างทัวร์นาเมนต์ผ่านคำขอ POST ที่มีเนื้อความ JSON การแข่งขันจะถูกแทรกใน a BiMapประกาศดังต่อไปนี้ในการนำ DAO ไปใช้:

private BiMap<String, Tournament> tournaments = Maps.synchronizedBiMap(HashBiMap.create());

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

GET http://localhost:8080/eventscheduler/c15268ce-474a-49bd-a623-b0b865386f39

แต่ถ้าหากไม่พบการแข่งขันที่มีรหัสดังกล่าวล่ะ จนถึงตอนนี้ฉันกำลังตอบกลับ 204 ข้อ นิวเจอร์ซีย์กำลังทำเพื่อฉันเมื่อกลับมาnullจากหนึ่งในวิธีการของมัน นี่คือวิธีการที่สอดคล้องกับเส้นทางด้านบน:

@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Tournament getTournament(@PathParam("id") String id) {
    Optional<Tournament> optTournament = tournamentDao.getTournament(id);
    if (optTournament.isPresent())
        return optTournament.get();
    return null;
}

คำถามของฉันคือ: มันตกลงเพื่อคืนการ204: No Contentตอบสนองหรือควรเป็นการ404ตอบสนองแทนเนื่องจากไม่พบทรัพยากร?

หากฉันควรเปลี่ยนเป็น 404 คำถามที่ชัดเจน: ฉันควรเปลี่ยนลายเซ็นวิธีใช่ไหม ตั้งแต่ตอนนี้การแข่งขัน (ประเภทTournament) อาจไม่ได้รับการคืนวิธีการควรดูแตกต่างกัน ฉันควรใช้Responseประเภทนี้เป็นประเภทส่งคืนแทนหรือไม่

คำตอบ:


32

HTTP 204หมายถึงว่าสิ่งที่ถูกพบ แต่มันว่างเปล่า ยกตัวอย่างเช่นจินตนาการว่าคุณกำลังให้บริการล็อกไฟล์ผ่าน HTTP มีการร้องขอเช่นhttp://example.com/logs/[date-goes-here] ในวันที่ 18 พฤษภาคม 2015:

  • http://example.com/logs/2015-05-19จะกลับมาHTTP 404ซึ่งหมายความว่าไม่มีบันทึกเพราะดีมันยากที่จะบันทึกอนาคต

  • อย่างไรก็ตามhttp://example.com/logs/2015-05-18จะกลับมาHTTP 200พร้อมกับรายการบันทึกในเนื้อหาของการตอบกลับหรือHTTP 204หากไฟล์บันทึกถูกสร้างขึ้น แต่ยังไม่มีการบันทึกบันทึกสำหรับสิ่งนี้ วันที่

ถ้าคุณให้กรอบการตอบสนองต่อการร้องขอที่จะอนุมานว่าคุณจะพบรายการและรายการนี้เป็นที่ว่างเปล่าจึงnull HTTP 204แต่คุณควรที่จะแสดงให้กรอบที่เข้าไม่ได้อยู่เพื่อที่มันจะสร้างthrow new NotFoundException();HTTP 404

หากฉันควรเปลี่ยนเป็น 404 คำถามที่ชัดเจน: ฉันควรเปลี่ยนลายเซ็นวิธีใช่ไหม

ไม่คุณทำไม่ได้ throw new NotFoundException();นั่นคือสิ่งที่ดีเกี่ยวกับ มันจะทำงานไม่ว่าสิ่งที่เป็นประเภทผลตอบแทนที่แท้จริงของวิธีการของคุณ


5
จดพิเศษRFC 2616 การตอบสนอง 204 นั้นเป็นไปตามข้อกำหนดเฉพาะหากคุณไม่ได้รับเนื้อหาทั้งหมด ในระดับหนึ่งประเด็นของการตอบสนอง 204 ข้อคือการพูดว่า "ไม่มันไม่ใช่อุบัติเหตุที่ฉันไม่ได้ส่งคืนเนื้อหา" หากต้องการขยายตัวอย่างของ MainMa: หากเครื่องมือค้นหาบันทึกแยกไฟล์ข้อความออก (เช่น wrapper เล็ก ๆ รอบ ๆ ไฟล์บันทึกที่เพิ่งแยกไฟล์บันทึกออกตามที่เป็นอยู่) 204 จะเหมาะสมสำหรับไฟล์บันทึกเปล่า หากการตอบสนองเป็นวัตถุ JSON ว่างเปล่า (เช่น{content: ''}) การตอบสนอง 204 ครั้งจะไม่เหมาะสม
Brian

" เพราะก็ยากที่จะบันทึกอนาคต " - บิตนี้ขึ้นอยู่กับวันที่โดยพลการ; ทำไมไม่ทำให้มันเป็นสิ่งที่ไม่ต้องการให้ผู้อ่านแสร้งทำเป็นไม่ใช่วันนี้? บางทีการใช้อาจ2015-02-29จะดีกว่าเนื่องจากเป็นวันที่ไม่มีอยู่หรือ
คดีของกองทุนโมนิกา

3

คุณควรส่งคืน 404 คุณสามารถทำได้โดยการโยน NotFoundException ( https://jersey.java.net/apidocs/2.6/jersey/javax/ws/rs/NotFoundException.html )

นอกจากนี้โปรดดูคำถาม SO นี้หากคุณต้องการควบคุมประเภทเนื้อหาที่คืนมา/programming/23858488/how-i-return-http-404-json-xml-response-in-jax-rs-ประเภทเนื้อหาที่ส่งคืนเสื้อ-on-คราว


1

GET http://localhost:8080/eventscheduler/c15268ce-474a-49bd-a623-b0b865386f39คำขอของคุณ

หากhttp://localhost:8080/eventscheduler/ไม่มีอยู่เป็นจุดสิ้นสุดคุณควรส่งคืน 404 คุณกำลังพยายามเข้าถึงทรัพยากร ( /eventscheduler/) ที่ไม่มีอยู่ สิ่งนี้จะบ่งบอกถึงไคลเอนต์ที่เซิร์ฟเวอร์มีอยู่localhost:8080แต่ไม่มีอะไรที่eventschedulerจุดสิ้นสุด

หากhttp://localhost:8080/eventscheduler/มีอยู่เป็นจุดสิ้นสุด แต่ทรัพยากรที่ต้องการไม่พร้อมใช้งานข้อผิดพลาด 5xx นั้นเหมาะสม ตัวอย่างที่ดีของกรณีนี้คือถ้าฐานข้อมูลออฟไลน์ซึ่งคุณสามารถส่งคืน 503 ได้แน่นอนคุณอาจต้องการส่งคืนข้อผิดพลาดทั่วไป 500 แทนที่จะเป็นอินสแตนซ์ที่เฉพาะเจาะจง

หากhttp://localhost:8080/eventscheduler/มีอยู่ แต่ไม่มีสิ่งที่แสดงโดยc15268ce-474a-49bd-a623-b0b865386f39ฉันจะกลับ 200 กับร่างกายที่ระบุรายละเอียด ปลายทางมีอยู่การร้องขอที่ทำนั้นถูกต้องทั้งหมดและสามารถประมวลผลได้ แต่ไม่มีการจับคู่

หากคำขอของลูกค้าของคุณไปยังปลายทางไม่ถูกต้องคุณจะพบข้อผิดพลาด 4xx อื่น ๆ คุณสามารถระบุว่าลูกค้าไม่ได้รับอนุญาตให้เข้าถึงปลายทางหรือรายการที่ร้องขอด้วย 401 หรือ 403 หรือสามารถใช้ 400 เพื่อระบุว่าคำขอนั้นไม่ถูกต้อง ด้วยสิ่งเหล่านี้ข้อมูลเพิ่มเติมสามารถให้ในการตอบสนองเนื้อความ


ไม่จำเป็นต้องแยกแยะความแตกต่างระหว่างอุปกรณ์ปลายทางและทรัพยากร หาก URI ไม่ตรงกับทรัพยากรใด ๆ ไม่ว่าด้วยเหตุผลใดก็ตามเซิร์ฟเวอร์ควรส่งคืน 404
bdsl

ตรวจสอบรหัสตอบสนองบนไซต์นี้เพื่อดูตัวอย่างของไซต์ที่ทำสิ่งที่ถูกต้อง เป็นเว็บไซต์ไม่ใช่ API แต่ใช้ข้อกำหนด HTTP เดียวกัน softwareengineering.stackexchange.com/questions/266183385
bdsl

@ bdsl ฉันบอกได้เลยว่ามันผิดอย่างแน่นอน ตัวอย่างเช่นฉันกำลังโต้ตอบกับบริการผู้ใช้ที่สามารถส่งคืนโปรไฟล์ผู้ใช้ สมมติว่าปลายทางนี้อยู่และมีการใช้เช่น/user /user?email=test@example.comในฐานะผู้บริโภค API ฉันต้องการทราบว่า/userด้วยเหตุผลบางอย่างไม่มีอยู่บนเซิร์ฟเวอร์ (อาจจะถูกเพิ่มใน v2 ของ API และเซิร์ฟเวอร์อยู่บน v1 หรือถูกเปลี่ยนชื่อเป็น v3) หรือหากผู้ใช้ที่มีอีเมลtest@example.comไม่มีตัวตน ที่แรกก็คือ 404 ที่สองคือ 200 ที่มีเนื้อหาที่ระบุว่าไม่มีผู้ใช้ที่อยู่อีเมลนั้น
โธมัสโอเวนส์

@bdsl ดี แต่นั่นไม่ได้หมายความว่าถูกหรือดีที่สุด ฉันยังไม่คิดว่าคุณสามารถเปรียบเทียบเว็บไซต์ที่ออกแบบมาสำหรับการโต้ตอบของมนุษย์ผ่านทางเว็บเบราว์เซอร์กับ API ที่ออกแบบมาเพื่อใช้ในระบบซอฟต์แวร์
โธมัสโอเวนส์

1
ปัญหานี้จะกล่าวถึงต่อไปในyoutube.com/watch?v=nSKp2StlS6s
bdsl
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.