Phản hồi mã trạng thái HTTP thích hợp cho một yêu cầu chung không thành công (không phải lỗi) là gì?


109

Tôi đang tạo một API RESTful sẽ xử lý một số tương tác của người dùng, bao gồm cả việc đặt hàng bằng thẻ tín dụng được lưu trữ.

Trong trường hợp đơn đặt hàng thành công, tôi trả lại 200 OK và trong trường hợp yêu cầu đặt hàng không đúng định dạng hoặc không hợp lệ, tôi trả lại 400 Yêu cầu không hợp lệ. Nhưng những gì tôi nên trả lại nếu có vấn đề trong quá trình xử lý thực tế của đơn đặt hàng?

  1. Đơn đặt hàng POSTS của máy khách đến máy chủ cho tài nguyên người dùng. Nếu người dùng không tồn tại, 404 Not Found sẽ được trả về.
  2. Định dạng đơn hàng và thông tin được xác thực. Nếu không hợp lệ, 400 Yêu cầu Không hợp lệ sẽ được trả lại.
  3. Đơn hàng đã được xử lý. Nếu đơn đặt hàng thành công, 201 Tạo được trả lại cho đơn đặt hàng. Nếu gặp lỗi không mong muốn, lỗi 500 Server được trả về.

Bước cuối cùng là vấn đề - tôi phải trả lại gì nếu đơn hàng không hoàn thành vì bất kỳ lý do nào khác? Các tình huống có thể xảy ra có thể bao gồm:

  • Sản phẩm đã bán hết
  • Người dùng đã đạt đến giới hạn đơn đặt hàng tối đa
  • Giao dịch thẻ tín dụng không thành công (không đủ tiền, v.v.)

Điều này có vẻ như không phù hợp với 400 hoặc 500. Nếu bất cứ điều gì tôi có thể thấy đó là 400 nếu không có mã tốt hơn - yêu cầu không hợp lệ theo quy tắc kinh doanh. Nó chỉ có vẻ không chính xác.

Chỉnh sửa: Cũng tìm thấy cuộc thảo luận hiện có này về cùng chủ đề. Tất cả các câu trả lời ở đó dường như đều hướng đến việc sử dụng mã trạng thái cho loại vi phạm này, với một số cuộc thảo luận giữa việc sử dụng 400, 409 hoặc 422.


8
Tôi thích '422 thực thể không thể xử lý' cho các lỗi xác thực. Và sẽ sử dụng nó cho các ví dụ ở trên của bạn, bao gồm thông báo trong phản hồi với vấn đề kinh doanh thực tế "Sản phẩm đã được bán hết" và có thể thêm 'mã' của riêng bạn nếu khách hàng cần lập trình đưa ra các quyết định khác nhau dựa trên phản hồi
house9

trước khi bạn nhảy vào 422, xem xét nếu bạn hỗ trợ khả năng WebDAV
Mbithy Mbithy

Câu trả lời:


90

Bạn nên sử dụng 400 cho các quy tắc kinh doanh. Không trả lại 2xx nếu đơn đặt hàng không được chấp nhận. HTTP là một giao thức ứng dụng, đừng bao giờ quên điều đó. Nếu bạn trả lại 2xx, khách hàng có thể cho rằng đơn đặt hàng đã được chấp nhận, bất kể bất kỳ thông tin nào bạn gửi trong nội dung.


Từ Sách nấu ăn của RESTful Web Services :

Một lỗi phổ biến mà một số dịch vụ web mắc phải là trả lại mã trạng thái phản ánh thành công (mã trạng thái từ 200 đến 206 và từ 300 đến 307) nhưng lại bao gồm nội dung thông báo mô tả tình trạng lỗi. Làm điều này ngăn phần mềm nhận biết HTTP phát hiện lỗi. Ví dụ, một bộ nhớ đệm sẽ lưu trữ nó dưới dạng phản hồi thành công và phục vụ nó cho các máy khách tiếp theo ngay cả khi máy khách có thể thực hiện một yêu cầu thành công.

Tôi sẽ để bạn quyết định giữa 4xx và 5xx, nhưng bạn nên sử dụng mã trạng thái lỗi.


1
Bạn có bất kỳ ví dụ hoặc tài liệu tham khảo nào cho cách tiếp cận này so với cách khác không? Cả câu trả lời của bạn và Widor đều có ý nghĩa, một từ quan điểm của HTTP như một giao thức ứng dụng và câu trả lời còn lại là hoàn toàn cho mục đích chuyển giao. Thông số định nghĩa nó là một "giao thức cấp ứng dụng", điều này hơi mơ hồ. Tôi cũng đã thấy cả quan điểm và ví dụ trên web khi nghiên cứu điều này.
Raelshark

Đúng đấy.
Young Hyun Yoo

2
Ý bạn là, 'Bạn nên sử dụng 4xx cho các quy tắc kinh doanh'?
Yawar

28

Bạn nên sử dụng 4xx cho lỗi máy khách nếu máy khách có thể sửa đổi yêu cầu để khắc phục lỗi. Sử dụng 5xx cho lỗi máy chủ mà máy khách không thể thực sự khắc phục được.

Sản phẩm bán hết sẽ là lỗi máy chủ. Khách hàng không thể sửa đổi yêu cầu theo một cách nào đó để khắc phục lỗi. Bạn có thể chuyển sang sản phẩm khác nhưng đó không phải là một yêu cầu mới?

Người dùng đạt đến giới hạn đơn đặt hàng tối đa cũng là lỗi máy chủ. Không có gì khách hàng có thể làm để khắc phục lỗi đó.

Lỗi giao dịch thẻ tín dụng sẽ là lỗi của khách hàng. Khách hàng có thể gửi lại yêu cầu bằng một phương thức thanh toán hoặc số thẻ tín dụng khác để khắc phục lỗi.


6
Nếu đạt đến giới hạn đơn đặt hàng, khách hàng không nên cảnh báo người dùng về điều đó và để họ thay đổi yêu cầu một cách thích hợp? Đó có vẻ như là lỗi 4xx. Tương tự đối với sản phẩm được bán hết. Lỗi 5xx dành cho các lỗi do hệ thống bị hỏng theo một cách nào đó, không phải cho một hành động không được phép theo quy tắc kinh doanh.
carlin.scott

7
Tôi đồng ý với nhận xét trên. Lỗi 5xx dành cho khi máy chủ có vấn đề. 4xx lỗi cho các quy tắc kinh doanh.
Merc

21

Loại lỗi:

4×× Client Error

Mã lỗi:

422 Unprocessable Entity

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 Loại phương tiện không được hỗ trợ 415 là không phù hợp) và cú pháp của thực thể yêu cầu là đúng (do đó mã trạng thái 400 Yêu cầu không phù hợp là không phù hợp) nhưng không thể xử lý nội dung chứa hướng dẫn.

Ví dụ, điều kiện lỗi này có thể xảy ra nếu một phần thân yêu cầu XML chứa các hướng dẫn XML được tạo hình tốt (tức là đúng về mặt cú pháp), nhưng sai về mặt ngữ nghĩa, các hướng dẫn XML.

https://httpstatuses.com/422


16

Tôi biết câu hỏi này đã cũ, nhưng hôm nay tôi đã nghĩ ra câu hỏi tương tự. Nếu người dùng của tôi hết tín dụng, thì REST API của tôi sẽ trả về mã trạng thái nào?

Tôi có xu hướng nghiêng về 402 Payment Required:

Theo Wikipedia :

Để dành mai sau dùng. Mục đích ban đầu là mã này có thể được sử dụng như một phần của một số hình thức tiền mặt kỹ thuật số hoặc chương trình thanh toán vi mô, nhưng điều đó đã không xảy ra và mã này thường không được sử dụng. API nhà phát triển của Google sử dụng trạng thái này nếu một nhà phát triển cụ thể đã vượt quá giới hạn yêu cầu hàng ngày.

Và thực sự họ làm :

PAYMENT_REQUIRED (402)

  • Đã đạt đến giới hạn ngân sách hàng ngày do nhà phát triển đặt.
  • Hoạt động được yêu cầu yêu cầu nhiều tài nguyên hơn hạn ngạch cho phép. Thanh toán được yêu cầu để hoàn thành hoạt động.
  • Hoạt động được yêu cầu yêu cầu một số loại thanh toán từ người dùng đã xác thực.

Đây là câu trả lời đáng suy nghĩ và hợp lý nhất.
GTodorov

5

Làm thế nào về 424 Failed Dependency? Thông số mô tả nó là:

Không thể thực hiện phương pháp trên tài nguyên vì hành động được yêu cầu phụ thuộc vào một hành động khác và hành động đó không thành công.

Nhưng cũng có định nghĩa này :

Mã trạng thái 424 được định nghĩa trong tiêu chuẩn WebDAV và dành cho trường hợp máy khách cần thay đổi những gì nó đang làm - máy chủ không gặp bất kỳ sự cố nào ở đây.

Bạn có thể nói với khách hàng (hoặc giả vờ) rằng bạn có các hành động nội bộ được cho là để tạo đơn hàng và khấu trừ số dư, và một trong những hành động đó không thành công, mặc dù vì những lý do hoàn toàn hợp lệ và đó là lý do tại sao yêu cầu không thành công.

Theo như tôi thấy, "hành động" là một thuật ngữ khá rộng và có thể được sử dụng trong nhiều trường hợp khác nhau, bao gồm không đủ hàng, không đủ tín dụng hoặc đêm tiệc trong kho.


Một tùy chọn khác có thể là 422 Unprocessable Entity:

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 Loại phương tiện không được hỗ trợ 415 là không phù hợp) và cú pháp của thực thể yêu cầu là đúng (do đó mã trạng thái 400 Yêu cầu không phù hợp là không phù hợp) nhưng không thể xử lý nội dung chứa hướng dẫn.

Ví dụ, điều kiện lỗi này có thể xảy ra nếu một phần thân yêu cầu XML chứa các hướng dẫn XML được tạo hình tốt (tức là đúng về mặt cú pháp), nhưng sai về mặt ngữ nghĩa, các hướng dẫn XML.

Cố gắng yêu cầu một mặt hàng đã hết hàng hoặc khi bạn không có đủ tín dụng, có thể bị coi là một sai lầm ở cấp độ ngữ nghĩa.

MozDev cho biết điều này chỉ ra một sai lầm từ phía khách hàng, cụ thể là: Khách hàng không nên lặp lại yêu cầu này mà không sửa đổi.

Loopback 4 sử dụng 422 khi xác thực đầu vào không thành công.


Có thể cho rằng, không đủ hàng hoặc đêm tiệc trong kho có thể được coi là trạng thái tạm thời, vì vậy yêu cầu có thể được thử lại sau. Tình huống đó có thể được chỉ ra bởi503 Service Unavailable

Máy chủ hiện không thể xử lý yêu cầu do quá tải tạm thời hoặc bảo trì theo lịch trình, có thể sẽ bị giảm bớt sau một thời gian trì hoãn.

Máy chủ CÓ THỂ gửi trường tiêu đề Thử lại Sau để đề xuất khoảng thời gian thích hợp để máy khách chờ trước khi thử lại yêu cầu.


Không ai trong số đó liên quan đến một khoản thanh toán. Tôi sẽ với 402 từ câu trả lời trước!
GTodorov

2

Tôi không nghĩ 400 có thể được sử dụng cho tất cả các tình huống kinh doanh. Nó có thể được sử dụng để xác nhận đầu vào dữ liệu cơ bản. Ngoài ra, chúng tôi có thể khó có thời gian để điều chỉnh logic nghiệp vụ khác vào mã lỗi này. Lỗi được xử lý bởi điều này chủ yếu là lỗi thời gian thiết kế mà nhà phát triển có thể gặp phải trong quá trình viết mã của máy khách.

Giả sử tất cả các tham số đều đúng và giả sử chúng tôi đang chuyển số tài khoản người dùng vào yêu cầu.

Vì vậy, yêu cầu giờ đây không còn là một yêu cầu xấu nữa, máy chủ có thể chấp nhận yêu cầu. Nhưng bây giờ nó đang từ chối hoàn thành yêu cầu dựa trên thông tin mới có sẵn - tài khoản không có đủ số dư.

Tôi khuyên chúng ta nên sử dụng 403 với thông báo lỗi thích hợp trong những trường hợp đó.

Mã lỗi có thể xảy ra khác có thể là xung đột 409. Nhưng điều đó được sử dụng trong các tình huống mà tài nguyên ở trạng thái nhất quán.


-1

Tôi đi với 406 Not Acceptable.

Đây là danh sách 4xx:

const HTTP_BAD_REQUEST = 400;
const HTTP_UNAUTHORIZED = 401;
const HTTP_PAYMENT_REQUIRED = 402;
const HTTP_FORBIDDEN = 403;
const HTTP_NOT_FOUND = 404;
const HTTP_METHOD_NOT_ALLOWED = 405;
const HTTP_NOT_ACCEPTABLE = 406;
const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
const HTTP_REQUEST_TIMEOUT = 408;
const HTTP_CONFLICT = 409;
const HTTP_GONE = 410;
const HTTP_LENGTH_REQUIRED = 411;
const HTTP_PRECONDITION_FAILED = 412;
const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
const HTTP_REQUEST_URI_TOO_LONG = 414;
const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
const HTTP_EXPECTATION_FAILED = 417;
const HTTP_I_AM_A_TEAPOT = 418;                                               // RFC2324
const HTTP_MISDIRECTED_REQUEST = 421;                                         // RFC7540
const HTTP_UNPROCESSABLE_ENTITY = 422;                                        // RFC4918
const HTTP_LOCKED = 423;                                                      // RFC4918
const HTTP_FAILED_DEPENDENCY = 424;                                           // RFC4918
const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425;   // RFC2817
const HTTP_UPGRADE_REQUIRED = 426;                                            // RFC2817
const HTTP_PRECONDITION_REQUIRED = 428;                                       // RFC6585
const HTTP_TOO_MANY_REQUESTS = 429;                                           // RFC6585

8
Mặc dù bản thân tên của mã trạng thái 406 có vẻ chính xác, nhưng bạn cần lưu ý rằng mỗi mã trạng thái có một mô tả văn bản có thẩm quyền. Mô tả cho mã trạng thái 406 không phù hợp với vỏ máy. Xem httpstatuses.com/406 chẳng hạn.
03

1
@ Zero3 nói đúng, mã này có nghĩa là loại phản hồi không được chấp nhận, vì có sự không khớp giữa Tiêu đề chấp nhận được gửi từ máy khách và (các) Loại phương tiện được gửi bởi điểm cuối, ví dụ: ứng dụng / json so với văn bản / đồng bằng
Gregor
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.