400 vs 422 การตอบสนองต่อ POST ของข้อมูล


355

ฉันกำลังพยายามหารหัสสถานะที่ถูกต้องที่จะกลับมาในสถานการณ์ที่แตกต่างด้วย API "คล้ายกับ REST" ที่ฉันกำลังทำงานอยู่ สมมติว่าฉันมีจุดสิ้นสุดที่อนุญาตให้มีการซื้อ POST ในรูปแบบ JSON ดูเหมือนว่านี้:

{
    "account_number": 45645511,
    "upc": "00490000486",
    "price": 1.00,
    "tax": 0.08
}

ฉันควรส่งคืนอะไรถ้าลูกค้าส่ง "sales_tax" ให้ฉัน (แทนที่จะเป็น "ภาษี" ที่คาดหวัง) ปัจจุบันฉันส่งคืน 400 แต่ฉันเริ่มตั้งคำถามกับตัวเอง ฉันควรจะส่งคืน 422 หรือไม่ ฉันหมายถึงมันคือ JSON (ซึ่งได้รับการสนับสนุน) และเป็น JSON ที่ถูกต้อง แต่มันไม่ได้มีฟิลด์ที่จำเป็นทั้งหมด


คำตอบ:


419

400 คำขอไม่ถูกต้องจะเป็นรหัสสถานะ HTTP / 1.1 ที่ดีที่สุดสำหรับกรณีการใช้งานของคุณ

ในช่วงเวลาของคำถามของคุณ (และคำตอบเดิมของฉัน) RFC 7231ไม่ได้เป็นอย่างนั้น ที่จุดที่ฉันคัดค้าน400 Bad RequestเพราะRFC 2616กล่าวว่า (ด้วยการเน้นการเหมือง):

การร้องขอไม่สามารถเข้าใจได้โดยเซิร์ฟเวอร์เนื่องจากไวยากรณ์ไม่ถูกต้อง

และคำขอที่คุณอธิบายนั้นเป็น JSON ที่ถูกต้องทางไวยากรณ์ที่เข้ารหัสใน HTTP ที่ถูกต้องทางไวยากรณ์และทำให้เซิร์ฟเวอร์ไม่มีปัญหาเกี่ยวกับไวยากรณ์ของคำขอ

อย่างไรก็ตาม ในขณะที่ออกมาชี้โดยลี Saferite ในการแสดงความคิดเห็น , RFC 7231 ซึ่ง obsoletes RFC 2616 ไม่รวมถึงข้อ จำกัด ว่า :

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


อย่างไรก็ตามก่อนที่จะมีถ้อยคำใหม่ (หรือหากคุณต้องการพูดเล่นเกี่ยวกับ RFC 7231 เป็นเพียงมาตรฐานที่เสนอในตอนนี้) 422 Unprocessable Entityดูเหมือนจะไม่ได้รหัสสถานะ HTTP ที่ไม่ถูกต้องสำหรับกรณีการใช้งานของคุณเพราะตามที่แนะนำ RFC 4918 กล่าวว่า:

ในขณะที่รหัสสถานะที่จัดทำโดย HTTP / 1.1 นั้นเพียงพอที่จะอธิบายเงื่อนไขข้อผิดพลาดส่วนใหญ่ที่พบโดยวิธีการของ WebDAV แต่ก็มีข้อผิดพลาดบางอย่างที่ไม่ได้อยู่ในหมวดหมู่ที่มีอยู่อย่างเรียบร้อย ข้อมูลจำเพาะนี้กำหนดรหัสสถานะเพิ่มเติมที่พัฒนาขึ้นสำหรับวิธี WebDAV (ส่วนที่ 11)

และคำอธิบายของ422พูดว่า:

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

(สังเกตการอ้างอิงถึงไวยากรณ์ฉันสงสัยว่า 7231 บางส่วนเลิก 4918 ด้วย)

เสียงนี้ว่าเหมือนสถานการณ์ของคุณ แต่เพียงในกรณีที่มีข้อสงสัยใด ๆ ก็กล่าวต่อไป:

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

(แทนที่ "XML" ด้วย "JSON" และฉันคิดว่าเราสามารถยอมรับได้ว่าเป็นสถานการณ์ของคุณ)

ทีนี้บางคนจะคัดค้านว่า RFC 4918 นั้นเกี่ยวกับ "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)" และคุณ (น่าจะเป็น) ที่กำลังทำอะไรที่เกี่ยวข้องกับ WebDAV ดังนั้นไม่ควรใช้อะไรจากมัน

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

นอกจากนี้RFC 4918 ส่วนที่ 21.4อ้างถึงIANA Hypertext Transfer Protocol (HTTP) รหัสสถานะการลงทะเบียนซึ่งสามารถพบ 422

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


แต่เป็น HTTP / 1.1, RFC 7231มีแรงฉุดดังนั้นให้ใช้400 Bad Request!


5
คำตอบของคุณ (422) เหมาะสมกับฉัน นี่คือสิ่งที่ Rails ( response_with ) ใช้เมื่อไม่สามารถประมวลผลทรัพยากรได้เนื่องจากข้อผิดพลาดในการตรวจสอบความถูกต้อง
Tyler Rick

11
โปรดสังเกตการใช้ 422 ในข้อมูลจำเพาะที่ไม่ใช่ WebDAV ที่นี่: tools.ietf.org/html/rfc5789#section-2.2
Andrey Shchekin

4
เช่นเดียวกับการอัปเดต RFC 7231 มีคำอธิบายที่แตกต่างกันสำหรับรหัสตอบกลับ 400 ที่เปลี่ยนซีแมนทิกส์
Lee Saferite

5
คำขอโทษของฉัน - ฉันอัปเดตคำตอบนี้เพื่อสะท้อนถึงการเปลี่ยนแปลงใน RFC และสูญเสียความชัดเจน; ฉันจะพยายาม refactor มันเกือบจะปลอดภัยแล้วที่จะใช้ 422 แต่ทุกวันนี้คุณควรใช้ 400
Kristian Glass

2
ฉันยังคิดว่าข้อมูลจำเพาะอาจชัดเจนกว่านี้มาก ตัวอย่างที่ให้ไว้ในกรณีที่ชัดเจนของลูกค้าที่ทำอะไรผิด สถานการณ์ของ OP ยังอยู่ในหมวดหมู่นั้น อย่างไรก็ตามมีหลายกรณีเช่น "ฉันเข้าใจสิ่งที่คุณขอ แต่ฉันปฏิเสธที่จะทำเพราะมีกฎเกณฑ์ทางธุรกิจบางอย่างต่อต้าน" ไม่ชัดเจนนัก ไม่ใช่ความผิดของลูกค้าดังนั้นอาจมีการนำ 403 มาใช้จริงตามข้อกำหนดเดียวกัน: "อย่างไรก็ตามคำขออาจถูกห้ามด้วยเหตุผลที่ไม่เกี่ยวข้องกับข้อมูลรับรอง" ฉันต้องการให้มีรหัสแยกต่างหากสำหรับสิ่งที่เกี่ยวข้องกับการอนุญาตเทียบกับ "ไม่สามารถทำได้"
Thorarin

37

400 คำขอไม่ถูกต้องเป็นรหัสสถานะ HTTP ที่ถูกต้องสำหรับกรณีการใช้งานของคุณ รหัสถูกกำหนดโดย HTTP / 0.9-1.1 RFC

เซิร์ฟเวอร์ไม่สามารถเข้าใจการร้องขอได้เนื่องจากไวยากรณ์ผิดรูปแบบ ลูกค้าไม่ควรทำซ้ำการร้องขอโดยไม่มีการดัดแปลง

http://tools.ietf.org/html/rfc2616#section-10.4.1

422 เอนทิตีที่ไม่สามารถประมวลผลได้ถูกกำหนดโดย RFC 4918 - WebDav โปรดทราบว่ามีความแตกต่างเล็กน้อยเมื่อเปรียบเทียบกับ 400 ดูข้อความที่ยกมาด้านล่าง

เงื่อนไขข้อผิดพลาดนี้อาจเกิดขึ้นหากเนื้อหาคำขอ XML มีรูปแบบที่ถูกต้อง (เช่นถูกต้องทางไวยากรณ์) แต่คำแนะนำ XML ผิดพลาด

เพื่อให้ส่วนต่อประสานที่เหมือนกันคุณควรใช้ 422 เฉพาะในกรณีของการตอบสนอง XML และคุณควรสนับสนุนรหัสสถานะทั้งหมดที่กำหนดโดยส่วนขยาย Webdav ไม่ใช่เพียง 422

http://tools.ietf.org/html/rfc4918#page-78

ดูโพสต์ของ Mark Nottingham ในรหัสสถานะ:

เป็นความผิดพลาดในการลองแมปแอปพลิเคชันแต่ละส่วนของคุณ“ ลึก” ลงในรหัสสถานะ HTTP ในกรณีส่วนใหญ่ระดับของความละเอียดที่คุณต้องการให้เล็งมีความหยาบมากขึ้น เมื่อสงสัยก็ตกลงที่จะใช้รหัสสถานะทั่วไป 200 ตกลง 400 ร้องขอไม่ถูกต้องและข้อผิดพลาด 500 บริการภายในเมื่อมีไม่ได้เป็นแบบที่ดีขึ้น

วิธีคิดเกี่ยวกับรหัสสถานะ HTTP


4
รหัส 422 เป็นส่วนหนึ่งของ IANA registry iana.org/assignments/http-status-codes/http-status-codes.xhtmlดังนั้น IMHO จึงไม่มีความหมาย ไม่ว่าในกรณีใด Facebook และ Twitter REST API จะสร้างรหัสของตัวเองใหม่และไม่ใช้มาตรฐาน RFC / IANA ดังนั้นคุณสามารถทำได้
gavenkoa

15
ส่วนที่ 11 ระบุว่าเป็นพิเศษพวกเขาจะถูกเพิ่มลงในข้อมูลจำเพาะทั้งหมดไม่ใช่เฉพาะในข้อมูลจำเพาะ WebDav:The following status codes are added to those defined in HTTP/1.1 [RFC2616].
Steve Tauber

8
เพียงเพราะมีการอธิบายรหัสเป็นส่วนหนึ่งของข้อมูลจำเพาะ WebDAV ไม่ได้หมายความว่าเฉพาะ WebDAV! รหัสสถานะควรเป็นรหัสทั่วไป
ปฏิบัติต่อ mods ของคุณดี

33

เพื่อสะท้อนสถานะของปี 2558:

พฤติกรรมทั้งรหัสการตอบสนอง 400 และ 422 จะได้รับการปฏิบัติเหมือนกันโดยลูกค้าและตัวกลางดังนั้นจริง ๆ แล้วมันไม่ได้สร้างความแตกต่างที่เป็นรูปธรรมที่คุณใช้

อย่างไรก็ตามฉันคาดว่าจะเห็น 400 ใช้ในวงกว้างมากขึ้นและชี้แจงเพิ่มเติมว่าHTTPbis specให้เหมาะสมยิ่งขึ้นของรหัสสถานะสอง:

  • ข้อมูลจำเพาะ HTTPbis ชี้แจงจุดประสงค์ของ 400 เพื่อไม่ให้เกิดข้อผิดพลาดทางไวยากรณ์เพียงอย่างเดียว วลีที่กว้างขึ้น "บ่งชี้ว่าเซิร์ฟเวอร์ไม่สามารถหรือไม่สามารถดำเนินการตามคำขอเนื่องจากบางสิ่งที่ถูกมองว่าเป็นข้อผิดพลาดของลูกค้า" ได้ถูกใช้แล้ว
  • 422 คือเฉพาะส่วนขยาย WebDAV และไม่ได้มีการอ้างอิงใน RFC 2616 หรือใหม่กว่าHTTPbis สเปค

สำหรับบริบท HTTPbis เป็นการแก้ไขข้อกำหนด HTTP / 1.1 ที่พยายามชี้แจงพื้นที่ที่ไม่ชัดเจนหรือไม่สอดคล้องกัน เมื่อถึงสถานะที่อนุมัติแล้วมันจะแทนที่ RFC2616


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

1
@garbagecollector โปรดทราบว่า "ปฏิเสธด้วยเหตุผลนอกเหนือจากข้อมูลประจำตัว "! = "ถูกปฏิเสธด้วยเหตุผลนอกเหนือจากการตรวจสอบสิทธิ์ " มีหลายวิธีในการตรวจสอบสิทธิ์บุคคลโดยไม่ต้องใช้ข้อมูลรับรองโดยเฉพาะ
Knetic

@garbagecollector ไม่ข้อมูลประจำตัวหมายถึงการตรวจสอบความถูกต้อง ("คุณเป็นใคร") ซึ่งจะเป็น 401 เมื่อล้มเหลว การอนุญาต ("คุณทำอะไรได้บ้าง") จะเป็น 403 เมื่อล้มเหลว คำอธิบายแบบสมบูรณ์ที่นี่: stackoverflow.com/a/6937030/137948 ไม่สามารถนำไปใช้กับสถานการณ์ "เขตข้อมูลที่ขาดหายไป" ของ OP ได้เนื่องจากข้อผิดพลาดจะเหมือนกันไม่ว่าผู้ใช้รายใดจะพยายามทำก็ตาม ฉันเห็นด้วย 400 เป็นคำตอบที่ถูกต้อง
Sheppard จะ

27

กรณีศึกษา: GitHub API

https://developer.github.com/v3/#client-errors

บางทีการคัดลอกจาก API ที่รู้จักกันดีเป็นความคิดที่ฉลาด:

ข้อผิดพลาดของไคลเอ็นต์ที่เป็นไปได้มีอยู่สามประเภทในการเรียก API ที่ได้รับเนื้อหาคำขอ:

การส่ง JSON ที่ไม่ถูกต้องจะส่งผลให้ 400 คำขอไม่ถูกต้อง

HTTP/1.1 400 Bad Request
Content-Length: 35

{"message":"Problems parsing JSON"}

การส่งค่า JSON ผิดประเภทจะส่งผลให้มีการร้องขอ 400 ครั้ง

HTTP/1.1 400 Bad Request
Content-Length: 40

{"message":"Body should be a JSON object"}

การส่งฟิลด์ที่ไม่ถูกต้องจะส่งผลให้เกิดการตอบสนองเอ็นติตี้ที่ไม่สามารถประมวลผลได้ 422

HTTP/1.1 422 Unprocessable Entity
Content-Length: 149

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "field": "title",
      "code": "missing_field"
    }
  ]
}

ฉันคิดว่านี่เป็นคำตอบที่ถูกต้องและเข้าใจได้
LEMUEL ADANE

1
ไม่สามารถลงคะแนนมากขึ้น หวังว่าคำตอบที่ถูกโหวตเพิ่มเติมจะอ้างถึงคำตอบนี้ ข้อมูลจำเพาะ (RFC, IANA) ล้มเหลวอย่างชัดเจนในการให้คำจำกัดความที่ชัดเจนและความแตกต่างระหว่างทั้งสอง ดังนั้นคำตอบก็คือการปฏิบัติที่ดีที่สุดและ GitHub ก็มอบสิ่งเหล่านี้ให้เรา
Alex Klaus

15

ไม่มีคำตอบที่ถูกต้องเนื่องจากขึ้นอยู่กับคำจำกัดความของ "ไวยากรณ์" สำหรับคำขอของคุณ สิ่งที่สำคัญที่สุดคือคุณ:

  1. ใช้รหัสการตอบกลับอย่างสม่ำเสมอ
  2. รวมข้อมูลเพิ่มเติมในส่วนการตอบกลับมากที่สุดเท่าที่จะทำได้เพื่อช่วยผู้พัฒนาโดยใช้ API ของคุณดูว่าเกิดอะไรขึ้น =

ก่อนที่ทุกคนจะกระโดดข้ามฉันไปเพราะบอกว่าไม่มีคำตอบที่ถูกหรือผิดฉันจะอธิบายให้ฉันฟังหน่อย

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

ในฐานะที่ผมกล่าวข้างต้นปัจจัยในการตัดสินใจเป็นสิ่งที่หมายโดยไวยากรณ์ หากคำขอถูกส่งด้วยประเภทเนื้อหาเป็นapplication/jsonใช่แล้วคำขอนั้นมีความถูกต้องทางไวยากรณ์เพราะเป็นไวยากรณ์ JSON ที่ถูกต้อง แต่ไม่ถูกต้องในเชิงความหมายเนื่องจากไม่ตรงกับที่คาดไว้ (สมมติว่าคำจำกัดความที่เข้มงวดของสิ่งที่ทำให้คำขอในคำถามมีความหมายถูกต้องหรือไม่)

หากในทางกลับกันคำขอนั้นถูกส่งไปพร้อมกับประเภทเนื้อหาที่กำหนดเองที่เจาะจงมากขึ้นเช่นapplication/vnd.mycorp.mydatatype+jsonนั้นอาจระบุว่าจะต้องระบุฟิลด์ใดอย่างแน่นอน

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


คำตอบที่มีค่าต่ำมาก - ขอบคุณสำหรับคำอธิบายที่ดี
puiu

ความคิดของฉันในเรื่อง! ฉันมาจากพื้นหลัง XML SOAP และแนวคิดของ schema เพิ่งเข้ามาในเลือดของฉันและเอกสาร JSON ค่อนข้างจะไม่ประกาศสคีมาของพวกเขา สำหรับฉันแล้วมันคือว่าเซิร์ฟเวอร์ "เข้าใจ" คำขอหรือไม่ หากเซิร์ฟเวอร์ไม่รู้ว่า "sales_tax" คืออะไรมันก็แค่ 400: "ฉันไม่รู้ว่าคุณส่งมาให้ฉัน แต่ไม่ใช่สิ่งที่ฉันต้องการอย่างแน่นอน"
Aleksander Stelmaczonek

4

422 คำอธิบายเอนทิตีที่ไม่สามารถประมวลผลได้อัปเดตแล้ว: 6 มีนาคม 2017

องค์กรที่ไม่สามารถประมวลผลได้ 422 คืออะไร

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

มีการโต้เถียงกันบ้างหรือไม่ว่านักพัฒนาซอฟต์แวร์ควรส่งคืนข้อผิดพลาด 400 vs 422 ถึงลูกค้า (เพิ่มเติมเกี่ยวกับความแตกต่างระหว่างสถานะทั้งสองด้านล่าง) อย่างไรก็ตามในกรณีส่วนใหญ่มีการตกลงกันว่าควรส่งคืนสถานะ 422 ต่อเมื่อคุณสนับสนุนความสามารถของ WebDAV

คำนิยามสำหรับคำต่อท้ายของรหัสสถานะ 422 ที่นำมาจากส่วนที่ 11.2 ใน RFC 4918 สามารถอ่านได้ด้านล่าง

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

คำจำกัดความกล่าวต่อไปว่า:

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

รหัสสถานะ 400 กับ 422

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

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

https://www.keycdn.com/support/422-unprocessable-entity/


1

กรณีของคุณ: HTTP 400เป็นรหัสสถานะที่ถูกต้องสำหรับกรณีของคุณจากมุมมอง REST เนื่องจากไม่ถูกต้องทางไวยากรณ์ในการส่งsales_taxแทนtaxแม้ว่าจะเป็น JSON ที่ถูกต้อง นี่คือการบังคับใช้ตามปกติโดยกรอบงานด้านเซิร์ฟเวอร์ส่วนใหญ่เมื่อทำการแมป JSON กับวัตถุ อย่างไรก็ตามมีการใช้งาน REST บางอย่างที่ไม่สนใจสิ่งใหม่keyในวัตถุ JSON ในกรณีนั้นcontent-typeข้อกำหนดเฉพาะที่กำหนดเองเพื่อยอมรับเฉพาะฟิลด์ที่ถูกต้องสามารถบังคับใช้โดยฝั่งเซิร์ฟเวอร์

สถานการณ์ที่เหมาะสำหรับ 422:

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

สถานการณ์ 400 มากกว่า 422:

จำไว้ว่ารหัสการตอบสนอง 422 เป็นรหัสสถานะ HTTP (WebDAV) แบบขยาย ยังมีบางห้องสมุดลูกค้า HTTP / front-end ที่ไม่ได้เตรียมที่จะจัดการ 422. สำหรับพวกเขามันเป็นง่ายๆเป็น"HTTP 422 เป็นความผิดเพราะมันไม่ได้เป็น HTTP" จากมุมมองการบริการ 400 ไม่ได้ค่อนข้างเฉพาะ

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

ในการจัดการสถานการณ์เช่นนี้เลเยอร์บริการมักใช้versioningหรือตั้งค่าconfigurationสถานะสำหรับไคลเอนต์ที่สอดคล้องกับ HTTP อย่างเข้มงวดเพื่อส่ง 400 และส่ง 422 สำหรับส่วนที่เหลือ ด้วยวิธีนี้พวกเขาให้การสนับสนุนความเข้ากันได้ย้อนหลังสำหรับผู้บริโภคที่มีอยู่ แต่ในขณะเดียวกันก็ให้ความสามารถสำหรับลูกค้าใหม่ที่จะใช้ HTTP 422


การอัปเดตล่าสุดเป็นRFC7321พูดว่า:

The 400 (Bad Request) status code indicates that the server cannot or
   will not process the request due to something that is perceived to be
   a client error (e.g., malformed request syntax, invalid request
   message framing, or deceptive request routing).

นี่เป็นการยืนยันว่าเซิร์ฟเวอร์สามารถส่ง HTTP 400 สำหรับคำขอที่ไม่ถูกต้อง 400 ไม่ได้อ้างถึงข้อผิดพลาดทางไวยากรณ์เท่านั้นอีกต่อไปอย่างไรก็ตาม 422 ยังคงเป็นคำตอบที่แท้จริงหากลูกค้าสามารถจัดการได้


1

ประการแรกนี่เป็นคำถามที่ดีมาก

400 คำขอไม่ถูกต้อง - เมื่อข้อมูลที่สำคัญขาดหายไปจากคำขอ

เช่นส่วนหัวการให้สิทธิ์หรือส่วนหัวประเภทเนื้อหา ซึ่งเซิร์ฟเวอร์จำเป็นอย่างยิ่งที่จะต้องเข้าใจคำขอ สิ่งนี้อาจแตกต่างจากเซิร์ฟเวอร์ไปยังเซิร์ฟเวอร์

422 เอนทิตีที่ไม่สามารถประมวลผลได้ - เมื่อไม่สามารถแยกวิเคราะห์เนื้อหาคำขอได้

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

เช่นContent-Type: application/xmlเมื่อเนื้อความคำขอคือ JSON

นี่คือรายการรหัสสถานะของบทความและการใช้งานใน REST API https://metamug.com/article/status-codes-for-rest-api.php


5
422 หมายความว่าไวยากรณ์นั้นถูกต้อง แต่เนื้อหาไม่ถูกต้อง การส่ง JSON โดยที่ XML คาดหมายว่าไวยากรณ์ผิดดังนั้น 400 จึงเป็นคำตอบที่ถูกต้องในกรณีนี้
เดิร์ค

1
ตรงตามที่ Dirk กล่าวว่า 422 หมายถึงคำขอที่ถูกต้องทางไวยากรณ์ (สามารถแยกวิเคราะห์และเข้าใจ) แต่ไม่ถูกต้องทางความหมาย
Jacek Obarymski

400: เมื่อคำขอไม่สามารถดำเนินการได้เนื่องจากไวยากรณ์ไม่ถูกต้อง (เช่นข้อผิดพลาดในการวิเคราะห์คำ); 422: เมื่อคำขอไม่สามารถดำเนินการได้เนื่องจากข้อมูลไม่ถูกต้อง (เช่นข้อผิดพลาดในการตรวจสอบ)
Kitanotori

ตัวอย่างของคุณสำหรับ 422 ไม่ถูกต้องเพราะโดยการส่ง json ด้วยชนิดของสื่อแอปพลิเคชัน / xml ร่างกายจะไม่ถูกต้องทางไวยากรณ์โดยอัตโนมัติและการตอบสนองควรเป็น 400
manemarron

-15

คุณควรส่งคืน "200 OK" และในเนื้อความการตอบกลับจะมีข้อความเกี่ยวกับสิ่งที่เกิดขึ้นกับข้อมูลที่โพสต์ จากนั้นขึ้นอยู่กับใบสมัครของคุณเพื่อทำความเข้าใจข้อความ

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

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

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

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

PS: รหัสสถานะ 422 มีความหมายเฉพาะในบริบทของ WebDAV หากคุณไม่ได้ทำงานกับ WebDAV ดังนั้น 422 จึงมีความหมายมาตรฐานเหมือนกับรหัสอื่นที่ไม่ใช่มาตรฐาน = ซึ่งไม่มีเลย

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