“ ไม่มีผลลัพธ์” ควรเป็นข้อผิดพลาดในการตอบสนองสงบหรือไม่?


52

ฉันจะอธิบายตัวอย่าง:
ฉันเริ่มทำ API สำหรับร้านเบเกอรี่ API api.examplebakery.com/search?q=.....ที่จะช่วยให้คนที่จะค้นหาแค็ตตาล็อกของพวกเขาสำหรับผลิตภัณฑ์เบเกอรี่เช่นทำที่บ้านมิ้นต์คุกกี้ช็อคโกแลตชิปใช้

มีคนใช้รายการนี้เพื่อค้นหาผลิตภัณฑ์ที่มีชื่อpineapple-banana flavoured cookiesและจะไม่พบผลลัพธ์ใด ๆ

ควรส่งคืนสิ่งนี้เป็นข้อผิดพลาดหรือไม่? การค้นหาไม่ล้มเหลว API ค้นหาและสรุปว่าประสบความสำเร็จไม่พบคุกกี้ API ไม่ควรส่งคืน404เนื่องจากพบ API จริงๆ



6
สำเนาที่เป็นไปได้ของRESTful API แสดงว่าไม่มีสิ่งใด
gnat

3
@gnat: นี่ไม่ใช่สิ่งที่ซ้ำกันเพราะคำถามอื่น ๆ เกี่ยวกับทรัพยากรที่เฉพาะเจาะจงไม่ใช่คำถามจากหลายแหล่งข้อมูล
Greg Burghardt

7
สมมติว่าคุณมีฟังก์ชั่นที่ส่งกลับอาร์เรย์ของวัตถุ หากไม่มีวัตถุใด ๆ ที่ตรงกับกรณีการใช้งานเฉพาะคุณต้องการให้ฟังก์ชันผ่านข้อยกเว้นหรือคืนอาร์เรย์ว่างเปล่าหรือไม่?
Kevin - Reinstate Monica

2
@AakashM การส่งคืน HTTP-204 ไปยังคำขอ GET นั้นค่อนข้างผิดปกติฉันรู้ว่าฉันไม่เคยเห็นที่ใดเลย เท่าที่ฉันทราบ HTTP-204 มักจะใช้เป็นการตอบสนองเมื่อแก้ไขทรัพยากรบนเซิร์ฟเวอร์ตัวอย่างเช่นคำขอ POST / PUT / DELETE
Radu Murzea

คำตอบ:


123

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

ดังนั้นหากการตอบกลับของคุณเป็นแบบนี้

{
    "results": [
        {
            "name": "Pancakes",
            ....
        },
        {
            "name": "French Fries",
            ....
        }
    ]
}

จากนั้นสำหรับแบบสอบถามที่มีผลลัพธ์ 0 รายการควรเป็นดังนี้:

{
    "results": []
}

หากคุณรวมข้อมูลเมตาเกี่ยวกับจำนวน "หน้า" ของผลลัพธ์ที่มีลิงก์ไปยัง "หน้า" เหล่านั้น ฯลฯ จากนั้นฉันขอแนะนำให้บอกว่ามี 1 "หน้า"

สถานะ HTTP ที่ควรจะเป็นเช่นเดียวกับเมื่อมีผลการค้นหา 200 OK-

204 No Contentอาจดูเหมือนเป็นตัวเลือก แต่ไม่ใช่เพราะคุณกลับมา "เนื้อหา" - รายการเปล่า หากคุณรู้สึกว่ารายการที่ว่างเปล่าไม่นับเป็น "เนื้อหา" จะทำอย่างไรถ้าคุณแก้ไขการตอบสนองเพื่อให้คำแนะนำการสะกดคำ หลักของการตอบสนองจะยังคงเป็นรายการที่ว่างเปล่า แต่ตอนนี้มี "เนื้อหา" มากขึ้น

สำหรับข้อมูลที่เป็นประโยชน์เพิ่มเติมเกี่ยวกับรหัสสถานะ HTTP, jpmc26 คำตอบคือควรอ่าน


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

54
ฉันขอยืนยันว่าการส่งคืน 204 ไม่เหมาะสมในขณะที่คุณส่งคืนเนื้อหา เป็นเพียงว่าเนื้อหาไม่มีผลลัพธ์ซึ่งแตกต่างจากการไม่ส่งคืนเนื้อหาเลย
TMN

9
@TMN ยอมรับ - 204 ไม่เหมาะสำหรับ "ไม่มีผลลัพธ์" แบบสอบถามของคุณควรส่งคืนอาร์เรย์เสมอโดยมีผลลัพธ์อยู่ภายในอาร์เรย์ หากไม่มีผลลัพธ์ลูกค้าจะจัดการกับสิ่งนั้นตามธรรมชาติ หากลูกค้าต้องการแสดงข้อความพิเศษ ("ไม่พบผลลัพธ์") แสดงว่าไม่เป็นไร 204 ควรส่งคืนสำหรับปลายทางที่ไม่ส่งคืนผลลัพธ์โดยธรรมชาติ
JasonB

1
คุณสามารถใช้ 204 หากคุณส่งคืนโมฆะต่อเนื่องเป็นสตริงที่ว่างเปล่าฉัน recon
Ewan

15
นี้. สิ่งสำคัญเมื่อสร้าง RESTful API คือส่วน API ไม่ใช่ restfullness API ที่ดีทำให้ชีวิตของลูกค้า / ผู้บริโภคเป็นเรื่องง่าย อาร์เรย์ว่างนั้นง่ายต่อการจัดการมากกว่าค่า null / ข้อยกเว้น / รหัสสถานะ
Guran

37

เมื่อใดก็ตามที่ตัดสินใจเลือกรหัส HTTP คุณควรถามคำถามนี้เสมอ:

ลูกค้าใดที่ต้องการและจะสามารถทำอะไรกับการตอบสนองได้?

  1. ควรลูกค้ามักจะปฏิบัติต่อการตอบสนองเป็นความล้มเหลว? จากนั้นคุณต้องการ 4xx หรือ 5xx ขึ้นอยู่กับว่าปัญหาคืออินพุตของลูกค้าหรือกระบวนการของเซิร์ฟเวอร์
  2. ลูกค้าควรทำการร้องขอที่อื่นแทนหรือไม่? จากนั้น 3xx สำหรับคุณ
  3. เซิร์ฟเวอร์ทำสิ่งที่ลูกค้าถาม (สำเร็จ) หรือไม่ นั่นคือ 2xx

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

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

ตอนนี้คำถามคือ "2xx ใด?" ขึ้นอยู่กับว่าคุณต้องการให้เซิร์ฟเวอร์ตอบสนองอย่างไร

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

คนอื่นไม่สามารถใช้งานได้เลย:

  • 201 อยู่นอกคำถาม คุณไม่ได้สร้างทรัพยากรถาวรใด ๆ และจะไม่ส่งคืนตำแหน่งไปยังทรัพยากรที่สร้างขึ้น
  • 202 เป็นไปไม่ได้ คำขอเสร็จสิ้น; มันไม่ได้ประมวลผลในพื้นหลัง
  • 203 หมายความว่าการตอบสนองถูกแก้ไขระหว่างเซิร์ฟเวอร์ที่เชื่อถือได้และลูกค้า อินเทอร์เฟซ RESTful ของคุณเป็นเซิร์ฟเวอร์ที่มีสิทธิ์ดังนั้นจึงไม่สามารถใช้งานได้ที่นี่
  • 205 ไม่สมเหตุสมผล คุณไม่ต้องการให้ลูกค้าล้างหรือรีเฟรชอะไรเลย
  • 206 ดูเหมือนจะได้รับการออกแบบมาเพื่อคืนทรัพยากรขนาดใหญ่ผ่านการตอบกลับที่หลากหลาย นอกจากนี้ยังต้องการให้ลูกค้าขอเป็นส่วนหนึ่งของเนื้อหาในส่วนหัว (ดังนั้นการแบ่งหน้าผ่านสตริงการสืบค้นไม่ผ่านการรับรอง) ไม่สามารถใช้ได้ที่นี่

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


5
จะมีความสนใจในความเห็นของผู้ลงคะแนน ฉันไม่คิดว่าสิ่งนี้จะขัดแย้งกัน
jpmc26

2
ฉันไม่คิดว่าลูกค้าจะต้องตรวจสอบ 204 อย่างชัดเจน สิ่งที่พวกเขาต้องการก็คือความสามารถในการจัดการกับวัตถุตอบสนองที่ไม่มีค่า เป็นหน้าที่ของเฟรมเวิร์ก HTTP ในการจัดการ 204 โดยการข้ามส่วน "แยกวิเคราะห์เนื้อหา" 200 กับ Content-Lenght 4 และnullของร่างกายนั้นเหมือนกัน
Agent_L

1
@Agent_L คุณพูดถูกว่าถ้าเซิร์ฟเวอร์ตอบสนองด้วยโครงสร้างที่ไม่สอดคล้องกับการตอบสนองปกติ (เช่นการใส่nullตำแหน่งที่มีรายการตามปกติ) คุณจะไม่ได้รับประโยชน์จากความสอดคล้องแม้จะเป็น 200 อย่างไรก็ตามสิ่งที่ฉันอธิบายคือการใช้ การตอบสนองที่สอดคล้องกับโครงสร้างปกติและมีรายการว่างที่รายการผลลัพธ์จะไปตามปกติ 204 ทำให้โอกาสใด ๆ ได้รับการตอบสนองที่สอดคล้องกัน นอกจากนี้แม้ในไลบรารีไคลเอ็นต์ HTTP ที่มีฟังก์ชั่นอำนวยความสะดวกคุณมักจะต้องทำการเรียก JSON เพื่อแยกวิเคราะห์ JSON อย่างชัดเจน
jpmc26

@Agent_L โดยเฉพาะอย่างยิ่งกับรายการผู้โทรสามารถปล่อยให้โค้ดของพวกเขาทำงานตามปกติในรายการที่ว่าง (โดยการวนซ้ำมัน) ในขณะที่พวกเขาต้องการการตรวจสอบที่ชัดเจนเพื่อจัดการกับการเป็นตัวแทนประเภทอื่น
jpmc26

16

ไม่การใช้ 404 เพื่อระบุว่า 'การสืบค้นของคุณได้รับการดำเนินการ แต่ไม่มีการจับคู่ที่ตรงกัน' นั้นน่ากลัวเพราะ:

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

  • ความกำกวมระหว่างหน้า 'ของจริง' ไม่พบคุณพิมพ์ข้อผิดพลาดปลายทางที่ผิด

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

ถ้าไคลเอ็นต์ควรส่งคืน null ให้ใช้การทำให้เป็นอนุกรมของ null หากลูกค้าควรส่งคืนอาเรย์ที่ว่างเปล่าให้ใช้ [] หากลูกค้าควรโยนข้อผิดพลาดใช้ 500 และส่งข้อความแสดงข้อผิดพลาด


2
เหตุใดเซิร์ฟเวอร์จึงต้องใส่ใจสิ่งที่ลูกค้ากำลังทำกับข้อมูล (PS: ฉันไม่ใช่คนที่ลดคำตอบของคุณ)
Radu Murzea

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

3
อย่าใช้ 5xx กับข้อผิดพลาดของลูกค้าแน่นอน ต้องการ 4xx ในกรณีนั้น
เควิน

1
แม้ว่าจะไม่ควรเป็น "เซิร์ฟเวอร์" ไม่ใช่ "ลูกค้า" ในกรณีส่วนใหญ่เหล่านี้ใช่ไหม เป็นเซิร์ฟเวอร์ที่ประมวลผลคำขอและตอบสนองลูกค้าเพียงแค่ประมวลผลการตอบสนองหรือไม่ ในกรณีใดรหัส 5xx จะตกลงเนื่องจากเป็นข้อผิดพลาดเซิร์ฟเวอร์ไม่ใช่ข้อผิดพลาดของลูกค้า?
MrWhite

2
ที่มีปัญหาทุกรหัสข้อผิดพลาดคือการที่พวกเขามีความหมายภายใน http 500 เป็นรหัสเดียวที่เหมาะสำหรับเมื่อบริการของคุณเกิดข้อผิดพลาด
Ewan

9

คำตอบที่ดีมากของ Beyond @ Ewan:

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

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


ใช่ฉันคิดว่าในคำตอบของ Ewan
Walfrat

5

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


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

0

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

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

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

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

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