Có nên sử dụng mã trạng thái HTTP để thể hiện lỗi logic nghiệp vụ trên máy chủ không?


20

Tôi đang ở một ngã rẽ với một số thiết kế API cho một khách hàng (JS trong trình duyệt) để nói chuyện với máy chủ. Chúng tôi sử dụng Xung đột HTTP 409 để thể hiện sự thất bại của một hành động vì khóa an toàn có hiệu lực. Khóa satefy ngăn các nhà phát triển vô tình thay đổi hệ thống sản xuất của khách hàng. Tôi đã được giao nhiệm vụ xử lý 409 một cách duyên dáng hơn trên máy khách để cho biết lý do tại sao một lệnh gọi API cụ thể không thành công.

Giải pháp của tôi là bọc các trình xử lý lỗi của bất kỳ cuộc gọi AJAX nào của chúng tôi sẽ hiển thị thông báo trên máy khách khi có sự cố do 409 - điều này hoàn toàn tốt và hoạt động tốt cùng với các lỗi 4XX và 5XX khác sử dụng cùng một cơ chế.

Một vấn đề đã phát sinh khi một trong những người xử lý tuyến đường của chúng tôi phản hồi với 409 giây khi gặp lỗi logic nghiệp vụ - trình bao bọc AJAX của tôi báo cáo rằng khóa an toàn được bật, trong khi trình xử lý lỗi hiện tại của khách hàng báo cáo vấn đề (nó nghĩ) là gì của phản ứng. Một giải pháp đơn giản sẽ là thay đổi phản hồi của trình xử lý hoặc mã trạng thái mà chúng ta sử dụng để thể hiện khóa an toàn.

Điều này đưa tôi đến ngã tư của mình: các mã trạng thái HTTP có nên được sử dụng để thể hiện các lỗi logic nghiệp vụ không? Câu hỏi này giải quyết cùng một vấn đề tôi đang gặp phải nhưng nó không đạt được nhiều sức kéo. Như được đề xuất trong câu trả lời được liên kết, tôi nghiêng về việc sử dụng HTTP 200 OK với phần thân thích hợp để thể hiện sự thất bại trong logic nghiệp vụ.

Có ai có bất kỳ ý kiến ​​mạnh mẽ ở đây? Có ai có thể thuyết phục tôi đây là cách sai để đại diện cho thất bại?


3
Tôi ngần ngại gửi ý kiến ​​đơn giản của tôi như là một câu trả lời. Tóm lại: Tôi thường tránh sử dụng mã trạng thái HTTP để biểu thị các lỗi kinh doanh. Họ chỉ nên liên quan đến trạng thái giao tiếp giữa máy khách và máy chủ. Mã trạng thái phù hợp để trả về xác thực hoặc lỗi logic nghiệp vụ sẽ là 400 Bad Request. Lý do cho sự tách biệt này là bởi vì các hệ thống, nhà phát triển hoặc người đọc tài liệu trong tương lai có thể bị nhầm lẫn bởi sự sai lệch của bạn về tiêu chuẩn trên toàn thế giới.
Ivo Coumans

@IvoCoumans: vui lòng thực hiện điều này ^ một câu trả lời để tôi có thể nâng cao nó. 400 Bad Requestvì mã HTTP có vẻ tốt nhất để che các lỗi logic nghiệp vụ như một lớp.
9000

Sở thích cá nhân, nhưng tôi có xu hướng sử dụng 400 Bad Requestkhi dữ liệu bị thiếu hoặc không thể đọc / phân tích cú pháp. Tức là dữ liệu yêu cầu tự nó là xấu theo một cách nào đó.
Kasey speakman

Vui lòng mở rộng về những gì bạn có nghĩa là "lỗi logic kinh doanh." Điều đó vô cùng mơ hồ. Bạn có nghĩa là đầu vào không phù hợp với kiểm tra xác thực dữ liệu (chính xác), đầu vào có thể hợp lệ tại một thời điểm khác nhưng không hợp lệ ở trạng thái hiện tại hoặc lỗi trong logic nghiệp vụ khi nó từ chối đầu vào hợp lệ?
jpmc26

@ jpmc26 Tôi đang cố tình mơ hồ vì đó là một câu hỏi chung. Các máy chủ đã xử lý yêu cầu tốt nhưng quyết định rằng truy vấn / xác nhận không có ý nghĩa.
Joe Shanahan

Câu trả lời:


19

Kasey bao gồm các điểm chính.

Ý tưởng chính trong bất kỳ api web nào: bạn đang điều chỉnh tên miền của mình trông giống như một cửa hàng tài liệu. NHẬN / PUT / POST / DELETE và như vậy là tất cả các cách tương tác với kho lưu trữ tài liệu.

Vì vậy, một cách suy nghĩ về việc sử dụng mã nào, là để hiểu hoạt động tương tự trong kho lưu trữ tài liệu là gì và sự thất bại này sẽ như thế nào trong tương tự đó.

2xx hoàn toàn không phù hợp

Lớp mã trạng thái 2xx (Thành công) cho biết rằng yêu cầu của khách hàng đã được nhận, hiểu và chấp nhận thành công.

5xx cũng không phù hợp

Lớp mã trạng thái 5xx (Lỗi máy chủ) cho biết rằng máy chủ biết rằng nó đã bị lỗi

Trong trường hợp này, máy chủ không mắc lỗi; nó nhận thức được rằng bạn không cần phải sửa đổi tài nguyên đó theo cách đó vào lúc này.

Lỗi logic nghiệp vụ (có nghĩa là bất biến doanh nghiệp không cho phép chỉnh sửa được đề xuất tại thời điểm này) có thể là 409

Mã trạng thái 409 (Xung đột) chỉ ra rằng yêu cầu không thể hoàn thành do mâu thuẫn với trạng thái hiện tại của tài nguyên đích. Mã này được sử dụng trong các tình huống mà người dùng có thể giải quyết xung đột và gửi lại yêu cầu. Máy chủ NÊN tạo ra một trọng tải bao gồm đủ thông tin để người dùng nhận ra nguồn gốc của xung đột.

Lưu ý bit cuối cùng này - tải trọng của phản hồi 409 sẽ truyền đạt thông tin cho người tiêu dùng về những gì đã sai và lý tưởng bao gồm các điều khiển hypermedia dẫn người tiêu dùng đến các tài nguyên có thể giúp giải quyết xung đột.

Giải pháp của tôi là bọc các trình xử lý lỗi của bất kỳ cuộc gọi AJAX nào của chúng tôi sẽ hiển thị thông báo trên máy khách khi có sự cố do 409 - điều này hoàn toàn tốt và hoạt động tốt cùng với các lỗi 4XX và 5XX khác sử dụng cùng một cơ chế.

Và tôi sẽ chỉ ra đây là vấn đề; việc triển khai của bạn tại máy khách cho rằng mã trạng thái là đủ để xác định vấn đề. Thay vào đó, mã khách hàng của bạn nên xem xét tải trọng và hành động theo thông tin có sẵn ở đó.

Rốt cuộc, đó là cách một cửa hàng tài liệu sẽ làm điều đó

409  Conflict

your proposed change has been declined because ${REASON}.  
The following resolution protocols are available: ${LINKS[@]})

Cách tiếp cận tương tự với a 400 Bad Requestcũng sẽ được chấp nhận; mà đại khái là "dịch thành" Có một vấn đề với yêu cầu của bạn. Chúng tôi không thể bận tâm để tìm ra mã trạng thái nào là phù hợp nhất, vì vậy bạn đến đây. Xem tải trọng để biết chi tiết. "

Tôi sẽ sử dụng 422. Đầu vào là hợp lệ vì vậy 400 không phải là mã lỗi đúng để sử dụng

Đặc tả WebDAV bao gồm khuyến nghị này

Mã trạng thái 422 (Thực thể không thể xử lý) có nghĩa là máy chủ hiểu loại nội dung của thực thể yêu cầu (do đó mã trạng thái 415 (Loại phương tiện không được hỗ trợ) là không phù hợp) và cú pháp của thực thể yêu cầu là chính xác (do đó là 400 (Yêu cầu sai ) mã trạng thái không phù hợp) nhưng không thể xử lý các hướng dẫn có trong đó. Ví dụ, điều kiện lỗi này có thể xảy ra nếu một thân yêu cầu XML chứa các hướng dẫn XML được định dạng đúng (nghĩa là đúng về mặt cú pháp), nhưng sai về mặt ngữ nghĩa, về mặt ngữ nghĩa.

Tôi không tin đó là một trận đấu hoàn toàn (mặc dù tôi đồng ý rằng điều đó làm thay đổi một số nghi ngờ 400thay thế). Giải thích của tôi 422có nghĩa là "bạn đã gửi sai thực thể" trong đó 409"bạn đã gửi thực thể không đúng lúc".

Đặt một cách khác, 422chỉ ra một vấn đề với thông báo yêu cầu được xem xét trong sự cô lập, trong đó 409chỉ ra rằng thông điệp yêu cầu mâu thuẫn với trạng thái hiện tại của tài nguyên.

Thảo luận của Ben Nadal về 422 có thể hữu ích để xem xét.


5
" bạn đang điều chỉnh tên miền của mình giống như một kho lưu trữ tài liệu " - Tôi rất thích thấy mọi người đọc nó và hiểu đầy đủ tất cả các điều khoản và hàm ý trước khi họ quyết định (hoặc chống lại) REST. Có thật không.
JensG

"Lỗi logic nghiệp vụ" nghe có vẻ như "đầu vào không hợp lệ", thường là 400 thường, vì không có mã lỗi cụ thể hơn cho nó. Nếu đó không phải là đầu vào không hợp lệ, thì máy chủ có lỗi và 500 là phù hợp. Câu trả lời của bạn dường như thừa nhận quá nhiều về bản chất của "lỗi logic kinh doanh".
jpmc26

Tôi sẽ sử dụng 422. Đầu vào là hợp lệ vì vậy 400 không phải là mã lỗi đúng để sử dụng
Konrad

19

Theo kinh nghiệm của tôi, mã lỗi HTTP không đủ để biểu thị các lỗi kinh doanh. Tuy nhiên, chúng rất hữu ích để đại diện cho các lớp lỗi.

Vì vậy, khuyến nghị của tôi là sử dụng mã lỗi HTTP cho các loại lỗi, nhưng chọn một lỗi cụ thể cho các lỗi logic nghiệp vụ (ví dụ: 409 Xung đột ... 200 OK sẽ gây hiểu nhầm ở đây) và bao gồm dữ liệu trong phản hồi cho biết lỗi kinh doanh cụ thể . Đảm bảo rằng đây là một phần của nội dung phản hồi và không phải là văn bản trạng thái vì một số trình duyệt bỏ qua văn bản trạng thái tùy chỉnh. Ngôn ngữ tôi muốn sử dụng có Loại liên kết thuận tiện cho việc thể hiện thông điệp. Nhưng bạn cũng có thể định nghĩa các hằng chuỗi cho các trường hợp lỗi.

Ví dụ

// error with text response
409 Conflict "safety_lock_engaged"
409 Conflict "customer_not_eligible_for_selected_discount"
// warning with JSON response
202 Accepted { "backorderedProductIds": [ 37, 476 ] }

Mã trạng thái 4xx trên 400 có ý nghĩa rất cụ thể. Chọn 400 nếu trường hợp của bạn không được bảo vệ bởi những người khác.
jpmc26

@ jpmc26 Nếu tôi không sử dụng mã trạng thái theo cách này thì chúng sẽ không bao giờ được sử dụng. Nhưng hãy thoải mái sử dụng chúng đúng cách và đúng đắn trong câu trả lời của bạn.
Kasey speakman

Theo một nghĩa nào đó, bạn đã đúng. Chúng không bao giờ được sử dụng. Các ý nghĩa được chọn cho các mã cụ thể dường như không phải là trường hợp sử dụng rất phổ biến cho hầu hết các ứng dụng. Không sao đâu. Có rất nhiều trường hợp ngoại lệ, chúng tôi cũng không bao giờ viết mã để bắt.
jpmc26

@ jpmc26 Ngoại lệ tốt không phải là mô hình tốt nhất để làm theo . Nhưng chắc chắn, đi trước.
Kasey speakman

Không ném hoặc bắt đối với các loại ngoại lệ cụ thể là tương tự không bao giờ sử dụng mã HTTP cụ thể hoặc bất kỳ mã lỗi nào khác. Tôi cho rằng điều này sẽ rõ ràng. Cho dù một mô hình ngoại lệ là "tốt nhất" hoàn toàn không liên quan đến điểm.
jpmc26

5

Nói chung, tôi sẽ tránh sử dụng mã trạng thái HTTP để biểu thị các lỗi logic nghiệp vụ cụ thể . Điều này là do chúng đã có một ý nghĩa ngữ nghĩa được xác định theo tiêu chuẩn toàn thế giới. Các hệ thống khác, nhà phát triển mới, v.v sẽ bị nhầm lẫn bởi sự sai lệch của bạn về tiêu chuẩn.

Những gì tôi tìm thấy trong nghiên cứu gần đây, tương tự, là nó thường được chấp nhận để sử dụng 400 Bad Requesttrong trường hợp có lỗi xác nhận và như vậy. Bằng cách này, bạn sử dụng một mã trạng thái cho tất cả các lỗi logic nghiệp vụ.

Ngẫu nhiên, 409nên được sử dụng khi tài nguyên đã thay đổi trong khi bạn chỉnh sửa nó và thử lưu lại.


4

Bạn có thể sử dụng "Yêu cầu xấu" và bao gồm id của quy tắc kinh doanh bị vi phạm cộng với một số chi tiết khác trên nội dung phản hồi.


Tôi không biết whey này đã được bỏ phiếu. Đây là cách các công ty có thể trả lại ngoại lệ kinh doanh.
Skadoosh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.