จะใช้รหัสสถานะ HTTP 404 ใน API เมื่อใด


58

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

เรากำลังเขียน API สำหรับระบบมีแบบสอบถามที่ควรส่งทรีขององค์กรหรือต้นไม้เป้าหมาย

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

ฉันจะพยายามทำให้เปลวไฟและความโกรธเคืองน้อยลง

ฉันแนะนำให้เพิ่มข้อผิดพลาด 404 เมื่อไม่มีต้นไม้ อย่างน้อยก็ให้ฉันรู้ว่ามีบางอย่างผิดปกติ เมื่อใช้ 200 ฉันต้องเพิ่มการตรวจสอบพิเศษในการตอบกลับของฉันในการติดต่อกลับสำเร็จเพื่อจัดการข้อผิดพลาด ฉันคาดหวังว่าจะได้รับวัตถุ แต่จริง ๆ แล้วฉันอาจได้รับการตอบสนองที่ว่างเปล่าเพราะไม่พบอะไรเลย มันฟังดูยุติธรรมมากที่จะทำเครื่องหมายการตอบรับเป็น 404 และจากนั้นสงครามก็เริ่มขึ้นและฉันได้รับข้อความว่าฉันไม่เข้าใจสกีมาโค้ดสถานะ HTTP ดังนั้นฉันมาที่นี่แล้วถามว่าเกิดอะไรขึ้นกับ 404 ในกรณีนี้ ฉันยังได้ข้อโต้แย้งว่า " ไม่พบอะไรเลยดังนั้นจึงถูกต้องที่จะคืน 200" ฉันเชื่อว่ามันผิดเพราะต้นไม้ควรมีอยู่เสมอ หากเราไม่พบอะไรและเราคาดหวังบางสิ่งมันควรจะเป็น 404

ข้อมูลเพิ่มเติม,

ฉันลืมที่จะเพิ่ม URL ที่ดึงมา

องค์กร

/OrgTree/Get

เป้าหมาย

/GoalTree/GetByDate?versionDate=...
/GoalTree/GetById?versionId=...

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

พิเศษ

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

ฉันยังเชื่อมโยงสิ่งนี้ด้วย (คล้ายกัน แต่ฉันหามันไม่เจอ)

http://viswaug.files.wordpress.com/2008/11/http-headers-status1.png


กรุณาชี้แจง: วิธีการสมัครสามารถกระจุยเมื่อมีต้นไม้ไม่มีถ้ามีอยู่เสมอต้นไม้โดยเงื่อนไข ? (ฉันเห็นด้วยกับคุณดูเหมือน 404)
Andres F.

รหัสไม่ได้ตรวจสอบหาค่าว่างและแยกวิเคราะห์สตริง json และเป็นวัตถุ ในบางสถานที่ในรหัสวัตถุที่ "เป็น" โหลดไม่ปรากฏขึ้นเนื่องจากไม่พบภายใน
Lo Fac Faure-Lacroix

4
มันจะชัดเจนกว่าถ้าคุณให้ URI สำหรับทรัพยากรที่คุณพยายามเข้าถึง ถ้ามัน / เป้าหมาย / คุณกลับ 200 และตั้งค่าว่างเปล่า หากคุณพยายามเข้าถึง / เป้าหมาย / {target_id} คุณจะได้รับผลตอบแทน 404 หากคุณส่งคืน 404 เพื่อขอ / ประตู / หมายความว่า URI นั้นไม่มีอยู่และไม่ควรใช้อีกต่อไป
imel96

1
ทั้งสองกรณียังมีคำถามอยู่ สิ่งที่ควร/GoalTree/GetById?versionId=CompletelyInvalidIDกลับมา? ไม่สำเร็จเนื่องจาก/GoalTree/GetById?versionId=CompletelyInvalidIDไม่พบทรัพยากรที่มีชื่อ

2
เยี่ยมมากตอนนี้การสนทนาเปลี่ยนจากการทำงานเป็น internets! ตอนนี้ผ่านพ้นไม่ได้แล้ว!
Carlos Campderrós

คำตอบ:


79

เมื่อสงสัยปรึกษาเอกสาร ตรวจสอบคำจำกัดความ W3C สำหรับรหัสสถานะ HTTP ให้สิ่งนี้แก่เรา:

200 ตกลง - คำขอสำเร็จแล้ว ข้อมูลที่ส่งคืนพร้อมการตอบกลับจะขึ้นอยู่กับวิธีที่ใช้ในคำขอ

404 Not Found - เซิร์ฟเวอร์ไม่พบสิ่งใดที่ตรงกับ Request-URI

ในบริบทของ API นั้นขึ้นอยู่กับวิธีสร้างคิวรีและวิธีดึงข้อมูลวัตถุ แต่การตีความของฉันเป็นเช่นนั้นเสมอ:

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

ดังนั้นในกรณีนี้คุณถูกต้องบริการไม่ได้ค้นหา "สิ่งที่เฉพาะเจาะจง" มันกำลังขอสิ่งใดสิ่งหนึ่งหากไม่พบสิ่งนั้นพูดอย่างชัดเจน

ฉันคิดว่า Wikipedia ทำให้ดีที่สุด:

200 ตกลง - ... การตอบสนองที่แท้จริงจะขึ้นอยู่กับวิธีการร้องขอที่ใช้ ในคำขอ GET การตอบสนองจะมีเอนทิตีที่สอดคล้องกับทรัพยากรที่ร้องขอ

404 ไม่พบทรัพยากรที่ร้องขอไม่สามารถพบได้ แต่อาจจะสามารถใช้ได้อีกในอนาคต คำขอต่อมาโดยลูกค้าที่ได้รับอนุญาต

ดูเหมือนจะชัดเจนกับฉัน

เกี่ยวกับคำขอตัวอย่าง

/GoalTree/GetByDate?versionDate=...
/GoalTree/GetById?versionId=...

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

อย่างไรก็ตามสิ่งหลังนั้นแตกต่างกันเมื่อคุณถามหาวัตถุเฉพาะซึ่งมีความเป็นเอกลักษณ์และมีเอกลักษณ์นั้น กลับมา200 OKในกรณีนี้คือผิดเป็นทรัพยากรที่ร้องขอไม่ได้อยู่และไม่พบ

เกี่ยวกับการเลือกรหัสสถานะ

  • รหัส 2xxบอก UA ว่าทำสิ่งที่ถูกต้องคำขอทำงาน มันสามารถทำสิ่งนี้ได้ในอนาคต
  • รหัส 3xxบอก UA ถึงสิ่งที่คุณถามว่าอาจใช้ในการทำงาน แต่ตอนนี้สิ่งนั้นอยู่ที่อื่น ในอนาคต UA อาจพิจารณาเพียงแค่จะเปลี่ยนเส้นทาง
  • รหัส 4xxบอก UA ว่าทำสิ่งผิดปกติคำขอที่สร้างขึ้นไม่เหมาะสมและไม่ควรลองอีกครั้งโดยไม่มีการดัดแปลงอย่างน้อย
  • รหัส 5xxบอก UA เซิร์ฟเวอร์ใช้งานไม่ได้ แต่เดี๋ยวก่อนว่าการสืบค้นสามารถทำงานได้ในอนาคตดังนั้นจึงไม่มีเหตุผลที่จะไม่ลองอีกครั้ง (ยกเว้น 501 ซึ่งมากกว่า 400 ฉบับ)

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

พิจารณาคนต่างด้าวที่ค้นหาระบบสุริยะของเรา

เอเลี่ยน: คอมพิวเตอร์โปรดบอกดาวเคราะห์ทั้งหมดที่มนุษย์อาศัยอยู่ด้วย

คอมพิวเตอร์: พบ 1 ผล โลก

คนต่างด้าว: คอมพิวเตอร์, โปรดบอกฉันเกี่ยวกับโลก

คอมพิวเตอร์: โลก - ไม่เป็นอันตรายมากที่สุด

เอเลี่ยน: คอมพิวเตอร์โปรดบอกฉันเกี่ยวกับดาวเคราะห์ทุกดวงที่มนุษย์อาศัยอยู่นอกแถบดาวเคราะห์น้อย

คอมพิวเตอร์: พบ 0 รายการ

เอเลี่ยน: คอมพิวเตอร์โปรดทำลายโลกด้วย

คอมพิวเตอร์: 200 ตกลง

คนต่างด้าว: คอมพิวเตอร์, โปรดบอกฉันเกี่ยวกับโลก

คอมพิวเตอร์: 404 - ไม่พบ

เอเลี่ยน: คอมพิวเตอร์โปรดบอกดาวเคราะห์ทั้งหมดที่มนุษย์อาศัยอยู่ด้วย

คอมพิวเตอร์: พบ 0 รายการ

เอเลี่ยน: ชัยชนะของอาณาจักร Irken อันยิ่งใหญ่!


4
+1 นี่ไม่ใช่แบบสอบถามที่ไม่มีผลลัพธ์ นี่เหมือนกับถามเบราว์เซอร์สำหรับหน้าเว็บที่รู้จักและไม่พบมัน สิ่งที่มีอยู่ 404 รายการ
Andres F.

2
@ imel96 คุณลืมว่าสตริงการสืบค้นเป็นส่วนหนึ่งของ URL
Loïc Faure-Lacroix

1
@LegoStormtroopr ตัวอย่าง "เอเลี่ยน" ที่น่าขบขันของคุณใช้งานได้เพราะจักรวาลไม่ถูกต้องเมื่อโลกไม่มีอยู่จริง แต่ตามคำอธิบายของ OP ระบบของเขาจะต้องรวมต้นไม้ หากไม่มีแผนผังระบบจะไม่ทำงาน
Andres F.

1
@LegoStormtroopr จินตนาการถึงตารางฐานข้อมูล คุณสอบถามตารางบางครั้งคุณได้รับผลบางครั้งคุณไม่ Table เป็นแหล่งข้อมูลของคุณอยู่เสมอโดยไม่คำนึงว่าจะส่งคืนแถวหรือไม่ ตารางสามารถระบุได้มันมีชื่อ (เช่นทรัพยากร http มี URIs) แถวนั้นไม่ตรงกับเพียงบางพารามิเตอร์เท่านั้น แม้ในฐานข้อมูลหากคุณอัปเดตซึ่งไม่ตรงกับอะไรเลยคุณจะได้รับ "ตกลง 0 แถวที่ได้รับผลกระทบ"
imel96

2
@LegoStormtroopr คุณมีคำตอบแล้ว หากพวกเขาต้องการทำการแมปใหม่ / GoalTree / GetById? versionId = x ก็ควรส่งคืน 301 โดยตั้งค่าส่วนหัวสถานที่ตั้งเป็น / GoalTree / Id / x
imel96

11

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

คุณใช้ 404 หากไม่พบทรัพยากรไม่ใช่เมื่อไม่มีเอนทิตี

วางไว้ในอีกทางหนึ่งถ้าคุณต้องการคืน 404 ให้กับวัตถุของคุณ


1
อืมมม มันสมเหตุสมผลแล้ว 404 เป็นข้อผิดพลาดของผู้ใช้แต่ตามที่ OP อธิบายนี่เป็นข้อผิดพลาดของระบบ คำขอของผู้ใช้นั้นสมบูรณ์แล้ว! ผมไม่เห็นด้วย 200 คือการตอบสนองที่เหมาะสม แต่เพราะ "ไม่มีต้นไม้" เป็นข้อผิดพลาด
Andres F.

@ imel96 ฉันต้องการให้เอนทิตีที่ถูกต้องถูกส่งคืนเสมอแทนที่จะว่าง / รหัสสถานะ 4xx / 5xx ถ้าเป็นเพียงฉันฉันจะคืนเอนทิตีที่ถูกต้องเช่นเดียวกับที่ wiki ทำ ปวดหัวน้อยลงไม่ต้องจัดการกับข้อผิดพลาด อย่างที่บอกไปแล้วว่ามันคล้ายกับ 500 ระบบอยู่ในสถานะที่ไม่ได้กำหนดไม่ควรเกิดขึ้น และการคืนตกลงก็ไม่สมเหตุสมผล 404 เกี่ยวกับ rfc ยังไม่สมเหตุสมผล ดังนั้นเมื่อไม่มีอะไรเหมาะสม ... เพียง 500 คนเท่านั้นที่เข้าท่า!
Loïc Faure-Lacroix

@Sybiam ดีคุณขอรหัสสถานะ http ซึ่งมีการกำหนดไว้เป็นอย่างดี ในเรื่องนี้แม้ว่าตรรกะทางธุรกิจของคุณบอกว่ามันเป็นข้อผิดพลาด แต่ก็ไม่ได้หมายความว่าระบบในฐานะเซิร์ฟเวอร์ HTTP มีข้อผิดพลาด ในกรณีของคุณมันเข้าใจคำขอของคุณมันประมวลผลแบบสอบถามของคุณและเพิ่งเกิดขึ้นว่าผลลัพธ์นั้นไม่มีเอนทิตี ดังนั้นคุณจึงไม่สามารถใช้ 500 ได้อย่างน้อยที่สุดควรพิจารณาให้ URI ของวัตถุของคุณเหมาะสมและดูว่า rfc เหมาะสมหรือไม่
imel96

+1 หากคุณมี REST API (แต่ละเอนทิตีมีเส้นทางของตัวเอง) คุณสามารถส่งคืน 404 แต่เส้นทางของคุณเป็นคำกริยาและจะพบได้ตลอดเวลา
OrangeDog

@OrangeDog: /GoalTree/GetById?versionId=12345 เป็น URI ที่ดีอย่างสมบูรณ์ (อย่างน้อยก็เกี่ยวข้องกันอย่างน้อย) ซึ่งระบุทรัพยากรที่เฉพาะเจาะจงนั่นคือข้อมูลที่สอดคล้องกับ ID เวอร์ชัน12345ในระบบ หากไม่มีข้อมูลที่มี ID ดังกล่าวการตอบสนอง HTTP 404 นั้นเหมาะสมอย่างยิ่ง แน่นอนว่าองค์กรตอบสนองควรมีการตอบสนองในรูปแบบที่เหมาะสม (เช่น JSON หากเป็นสิ่งที่ลูกค้าทั่วไปขอทรัพยากรดังกล่าวคาดหวัง) ระบุลักษณะเฉพาะและสาเหตุของข้อผิดพลาด
Ilmari Karonen

7

นี่เป็นคำถามที่น่าสนใจเพราะมันเกี่ยวกับสเปคของระบบ

การตอบสนองของ imel96ทำให้ฉันเชื่อว่า 404 จะไม่เป็นการตอบสนองที่เหมาะสมเนื่องจากรหัส 4xx เป็นส่วนใหญ่สำหรับข้อผิดพลาดของผู้ใช้ / ลูกค้าและนี่ไม่ใช่หนึ่งเดียว URL นั้นมีรูปแบบที่ดีและต้นไม้จะต้องอยู่ที่นั่น หากไม่เป็นเช่นนั้นระบบจะอยู่ในสถานะไม่สอดคล้องกัน!

ดังนั้นนี่เป็นข้อผิดพลาดของเซิร์ฟเวอร์นั่นคือมีบางอย่างในตระกูล 5xx อาจเป็นข้อผิดพลาดทั่วไปของเซิร์ฟเวอร์ภายใน 500 ข้อหรือ 503 บริการไม่พร้อมใช้งาน (บริการกำลัง "ดึงต้นไม้ที่ต้องมี" มาให้ฉัน)


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

@LegoStormtroopr การขอสิ่งที่ไม่มีอยู่จริงนั้นไม่ได้เป็นข้อผิดพลาดเสมอไป หากคุณขอทรัพยากรเครือข่ายและเครือข่ายไม่ทำงานแสดงว่าเป็นข้อผิดพลาดของเครือข่าย
Andres F.

1
@LegoStormtroopr นอกจากนี้ต้นไม้จะต้องมีอยู่; ระบบไม่สามารถทำงานได้หากไม่มีมันตามคำอธิบายของ OP ดังนั้นจึงถูกต้องที่จะขอทรัพยากรนี้ หากไม่มีอยู่จะต้องมีข้อผิดพลาดของระบบ (หรือเซิร์ฟเวอร์)
Andres F.

2
@Sybiam หากคุณกำลังจะไปเส้นทางของรหัส 5xx, 503 คือ "503 บริการไม่พร้อมใช้งาน - เซิร์ฟเวอร์ไม่สามารถจัดการคำขอได้ในขณะนี้เนื่องจากการโอเวอร์โหลดชั่วคราวหรือการบำรุงรักษาเซิร์ฟเวอร์" เซิร์ฟเวอร์ของคุณไม่โหลดมากเกินไปไม่พบคำขอ นอกจากนี้รหัส 5xx ใช้สำหรับเมื่อ "เซิร์ฟเวอร์ทราบว่ามีข้อผิดพลาดหรือไม่สามารถดำเนินการตามคำขอได้"

1
@AndresF ความซื่อสัตย์รหัส 500 น่าจะดี เมื่อคำถามมีการเปลี่ยนแปลงไปตามกาลเวลามันก็ใช้ได้ ส่วนใหญ่ฉันแค่ชุมนุมต่อต้านกลับ 200 ถ้าทุกอย่างไม่เป็นไร

6

ฉันจะบอกว่าทั้งรหัสตอบสนอง 200 หรือ 404 สามารถใช้ได้ขึ้นอยู่กับว่าคุณดูสถานการณ์

สิ่งนี้คือรหัสการตอบสนอง HTTPถูกกำหนดไว้ในบริบทของเซิร์ฟเวอร์ซึ่งสามารถส่งมอบทรัพยากรต่าง ๆตาม URL ของพวกเขา ในบริบทนี้ความหมายของ200 OKและ404 Not Foundไม่มีความชัดเจนอย่างสมบูรณ์แบบ: อดีตกล่าวว่า "นี่เป็นทรัพยากรที่คุณขอ" ในขณะที่คนหลังบอกว่า "ขอโทษฉันไม่มีทรัพยากรเช่นนั้น"

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

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

โดยเฉพาะอย่างยิ่งในกรณีตัวอย่างของคุณเว็บเซิร์ฟเวอร์สามารถค้นหาแอปพลิเคชันได้ดี แต่แอปพลิเคชันนั้นล้มเหลวในการค้นหาแหล่งข้อมูลย่อย (ต้นไม้) ที่ได้รับการร้องขอ ตอนนี้ถ้าคุณพิจารณาว่าแอปพลิเคชันเป็นเพียงส่วนขยายของเซิร์ฟเวอร์และ subitem (tree) เป็นทรัพยากรจริงดังนั้นการตอบสนอง 404จึงเหมาะสม: เซิร์ฟเวอร์ได้มอบหมายภารกิจในการค้นหาทรัพยากรจริงให้กับแอปพลิเคชัน ซึ่งมันล้มเหลวในการทำเช่นนั้น

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

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

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


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

ในระดับ HTTP ทรัพยากรที่ว่างเปล่าจะถูกระบุด้วยรหัสการตอบสนอง 200 รายการและเนื้อหาการตอบสนองที่ว่างเปล่าในขณะที่ทรัพยากรที่ไม่มีอยู่จะถูกระบุโดยการตอบสนอง 404 และเนื้อหาของทรัพยากรอธิบายถึงการขาดทรัพยากร ในโปรโตคอล API ระดับสูงกว่าปกติหนึ่งจะระบุทรัพยากรที่ไม่มีอยู่โดยการตอบสนองข้อผิดพลาดที่มีรหัสข้อผิดพลาดเฉพาะโปรโตคอลที่เหมาะสม / ในขณะที่การตอบสนองที่ว่างเปล่าก็จะเป็นโครงสร้างการตอบสนองปกติที่ไม่มีรายการข้อมูล

(โปรดทราบว่าทรัพยากรไม่จำเป็นต้องมีความยาวเท่ากับศูนย์อย่างแท้จริงว่าเป็น "ว่าง" ในแง่ที่ฉันหมายถึงข้างต้นตัวอย่างเช่นผลการค้นหาที่ไม่มีรายการที่ตรงกันจะนับว่าว่างเปล่าในวงกว้างเช่นเดียวกับผลลัพธ์คิวรี SQL ไม่มีแถวหรือเอกสาร XML ที่ไม่มีข้อมูลจริง)

นอกจากนี้แน่นอนถ้าแอพลิเคชันจริงๆไม่เชื่อว่า subresource ขอควรจะมี 500 Internal Server Errorแต่ไม่สามารถหาได้จากนั้นหนึ่งในสามรหัสการตอบสนองเป็นไปได้ที่มีอยู่: การตอบสนองดังกล่าวเหมาะสมหากการมีอยู่ของทรัพยากรเป็นเงื่อนไขเบื้องต้นสำหรับแอปพลิเคชันซึ่งหากไม่มีการระบุว่าจำเป็นต้องระบุความผิดปกติภายใน

สุดท้ายคุณควรเสมอเก็บไว้ในใจกฎหมายของพอส :

" ระมัดระวังในสิ่งที่คุณส่งและเสรีในสิ่งที่คุณได้รับ "

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


ภาวะที่กลืนไม่เข้าคายไม่ออกอธิบายอย่างดี
Marcel

ไม่มีภาวะที่กลืนไม่เข้าคายไม่ออก คำตอบนี้ไม่ได้ขึ้นอยู่กับทรัพยากรที่กำหนดไว้ใน rfc ที่เกี่ยวข้อง ดูความคิดเห็นของฉันภายใต้คำตอบ @LegoStormtroopr
imel96

@ imel96: ฉันคิดว่าคุณตีความผิด RFC 1630: ย่อหน้าที่คุณอ้างถึงในความคิดเห็นก่อนหน้านี้ของคุณอ่านเต็ม: "เครื่องหมายคำถาม ("? ", ASCII 3F hex) ถูกใช้เพื่อกำหนดขอบเขตระหว่าง URI ของแบบสอบถาม วัตถุและชุดของคำที่ใช้ในการแสดงการสืบค้นบนวัตถุนั้นเมื่อใช้แบบฟอร์มนี้URI ที่รวมกันจะย่อมาจากวัตถุซึ่งเป็นผลมาจากการสืบค้นที่นำไปใช้กับวัตถุดั้งเดิม " (เหมืองของฉัน) ดังนั้นจึงเป็นที่ชัดเจนว่าสตริงแบบสอบถามแน่นอนเป็นส่วนหนึ่งของ URI (แม้ว่าส่วนหนึ่งก่อนที่จะสตริงแบบสอบถามคือจำเป็นต้องยัง URI ที่ถูกต้องด้วยตัวเอง) ...
Ilmari Karonen

... และสิ่งนี้รวมกัน URI ระบุทรัพยากรเฉพาะที่ลูกค้าอาจร้องขอโดยการส่ง URI นั้นไปยังเซิร์ฟเวอร์ ไม่ว่าในกรณีใด RFC 2616 (HTTP) จะกำหนดทรัพยากรเป็น"วัตถุข้อมูลเครือข่ายหรือบริการที่ URI สามารถระบุได้ตามที่กำหนดไว้ในส่วน 3.2" และยังกล่าวต่อไปอีกว่า"เท่าที่มีความเกี่ยวข้องกับ HTTP ตัวระบุทรัพยากรอย่างสม่ำเสมอนั้นเป็นรูปแบบของสตริงที่ระบุว่า - ผ่านชื่อสถานที่หรือคุณสมบัติอื่น ๆ - ทรัพยากร"
Ilmari Karonen

@IlmariKaronen คุณพูดถูก ฉันสับสน HTTP กับ REST ยังดูเหมือนไม่ถูกต้องเพราะฉันไม่แน่ใจว่าคุณสามารถทำอะไรกับทรัพยากรด้วย URI เช่น / GoalTree / Get? versionDate = 2000BC
imel96

3

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


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

3

หาก URL แสดงถึงทรัพยากรที่ไม่เคยมีอยู่คืนมา 404 ไม่พบ

หาก URL แสดงถึงทรัพยากรที่เป็นรายการที่ว่างเปล่าส่งคืนรายการที่ว่างเปล่าและ 200 OK

ตัวอย่าง:

{
  total: 0,
  items: []
}

ถ้า URL แสดงถึงทรัพยากรที่เคยมีอยู่คืน 410 Gone

เกี่ยวกับบทสนทนาของ Lego Stormtrooper:

Alien: Computer, please tell me all planets that humans inhabit. GET /planets?inhabitedBy=humans

Computer: 200 OK. { total: 1, items:[{name:'Earth'}] }

Alien: Computer, please tell me about Earth. GET /planets/earth

Computer: 200 OK. {name:'Earth', status: 'Mostly Harmless'}

Alien: Computer, please tell me about all planets humans inhabit, outside the asteroid belt. GET /planets?inhabitedBy=humans&distanceFromSun=lots

Computer: 200 OK. {total:0, items:[] }

Alien: Computer, please destroy Earth. DELETE /planets/earth

Computer: 204 No Content. (or 202 Accepted if it takes some time to destroy Earth)

Alien: Computer, please tell me about Earth. GET /planets/earth

Computer: 410 Gone

Alien: Computer, please tell me all planets that humans inhabit. GET /planets?inhabitedBy=humans

Computer: 200 OK 0 {total: 0, items:[] }

Alien: Victory for the mighty Irken Empire!

1

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

ฉันเห็นด้วยกับขาตั้งของคุณว่าคุณควรได้รับรหัสสถานะที่แสดงว่ามีบางอย่างผิดปกติ นี่คือหลังจากทั้งหมดรหัสสถานะสำหรับ นอกจากนี้คุณยังได้รับประโยชน์จากห้องสมุดที่มีข้อยกเว้น / etc ในรหัสสถานะที่ไม่ใช่ 200 ดังนั้นคุณไม่จำเป็นต้องตรวจสอบอย่างชัดเจน (หรือคุณสามารถเขียน wrapper ของคุณเองที่ทำสิ่งนี้)

ฉันยังเห็นด้วยกับมุมมองของ Andres F. ว่า 500 มีความเหมาะสมเนื่องจากต้นไม้ควรมีอยู่ แม้ว่าในทางปฏิบัติแล้วฉันต้องการแบ่งข้อผิดพลาดของเซิร์ฟเวอร์ออกเป็นสองประเภท บางสิ่งบางอย่างที่ไม่คาดคิดที่ผิดพลาดและสิ่งที่ฉันจริงสามารถตรวจสอบผิดพลาด ผลลัพธ์นี้ในรหัสสถานะต่อไปนี้

  • 200 - ทุกอย่างดี
  • 404 - URL ผิด
  • 409 - มีบางอย่างผิดปกติ
  • 500 - มีข้อผิดพลาดที่ไม่คาดคิดเกิดขึ้นบนเซิร์ฟเวอร์

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

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

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

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


0

การแทงตามจุดสัมผัสที่นี่: ถ้าในที่สุดมนุษย์ก็ใช้ API (ผ่านทาง GUI) ฉันขอแนะนำให้ทำทุกอย่างที่ทำให้ชีวิตของผู้ใช้ง่ายขึ้น ไม่มีอยู่ของต้นไม้เมื่อมันควรมีอยู่เป็นข้อผิดพลาด "โดเมนแบบไม่สอดคล้องกัน" ข้อผิดพลาด ข้อผิดพลาดของระบบคือเมื่อคุณมีหน่วยความจำไม่เพียงพอหรือมีความล้มเหลวของระบบอื่น ๆ ดังนั้นการส่งคืน 5xx จึงไม่เหมาะสม ตามที่กล่าวไว้โดยหลายคนข้างต้น 4xx อาจเหมาะสมถ้าต้นไม้มี URI ของตัวเองซึ่งไม่ใช่กรณีที่นี่ แต่นี่คือสิ่งที่ 404 บอกลูกค้า: คุณสามารถลองอีกครั้งและอีกครั้งจนกว่าคุณจะได้อะไรกลับมา หากคุณส่งคืน 200 คุณสามารถส่งคืนการวินิจฉัยที่เพียงพอกลับไปยังผู้ใช้หรือตัวแทนผู้ใช้เพื่อให้ตัวแทนผู้ใช้สามารถแสดง meaaage เพื่อให้ผู้ใช้หยุดการลองอีกครั้งและเพียงแค่ติดต่อฝ่ายสนับสนุน ในทางตรงกันข้ามหาก API นี้มีไว้สำหรับระบบเท่านั้น


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

ฉันชอบความเป็นไปได้ที่จะแยกแยะความแตกต่างระหว่าง URL ที่ไม่พบและทรัพยากรไม่พบ ... ดังนั้น Service Endpoint จึงทำงานและทำงาน 200 อย่างไรก็ตามทรัพยากรที่ร้องขอไม่ได้พบที่ 404 (Response Body)
น้ำมะนาว
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.