Có sai khi trả về 202 "Đã chấp nhận" để phản hồi HTTP GET không?


88

Tôi có một tập hợp các tài nguyên có các đại diện được tạo một cách lười biếng. Việc tính toán để xây dựng các biểu diễn này có thể mất từ ​​vài mili giây đến vài giờ, tùy thuộc vào tải máy chủ, tài nguyên cụ thể và giai đoạn của mặt trăng.

Yêu cầu GET đầu tiên nhận được cho tài nguyên bắt đầu tính toán trên máy chủ. Nếu quá trình tính toán hoàn thành trong vòng vài giây, biểu diễn đã tính sẽ được trả về. Nếu không, mã trạng thái 202 "Được chấp nhận" sẽ được trả về và khách hàng phải thăm dò tài nguyên cho đến khi có bản đại diện cuối cùng.

Lý do cho hành vi này là sau: Nếu một kết quả có sẵn trong vòng vài giây, nó cần được truy xuất càng sớm càng tốt; nếu không, khi nào nó có sẵn là không quan trọng.

Do bộ nhớ hạn chế và khối lượng yêu cầu tuyệt đối, không phải NIO cũng như bỏ phiếu dài đều không phải là một lựa chọn ( tức là tôi không thể mở gần như đủ kết nối, thậm chí tôi không thể phù hợp với tất cả các yêu cầu trong bộ nhớ; một lần "vài giây" đã trôi qua, tôi vẫn tiếp tục các yêu cầu dư thừa). Tương tự như vậy, các giới hạn của ứng dụng khách là chúng không thể xử lý một cuộc gọi lại hoàn thành, thay vào đó. Cuối cùng, xin lưu ý rằng tôi không quan tâm đến việc tạo tài nguyên "nhà máy" mà một ĐĂNG đến, vì các vòng quay bổ sung có nghĩa là chúng tôi không thực hiện được ràng buộc thời gian thực từng mảnh nhiều hơn mong muốn (hơn nữa, nó phức tạp hơn; ngoài ra, đây là tài nguyên sẽ lợi ích từ bộ nhớ đệm).

Tôi tưởng tượng có một số tranh cãi về việc trả lại mã trạng thái 202 "Được chấp nhận" để phản hồi yêu cầu GET, như tôi chưa từng thấy trong thực tế và cách sử dụng trực quan nhất của nó là để đáp ứng các phương pháp không an toàn, nhưng tôi chưa bao giờ tìm thấy bất cứ điều gì đặc biệt làm nản lòng nó. Hơn nữa, có phải tôi đang không bảo vệ cả sự an toàn và tính hiệu quả?

Vậy, mọi người nghĩ gì về cách tiếp cận này?

CHỈNH SỬA : Tôi nên đề cập rằng điều này dành cho cái gọi là API web doanh nghiệp - không dành cho trình duyệt.


2
Cá nhân tôi nghĩ rằng đó là một trong những tốt, nó chính xác là định nghĩa của a 202. Rằng nó hiếm khi được sử dụng trong thực tế hơn là IMHO vì ít nhà phát triển web quan tâm đến mã trạng thái thích hợp vì họ quen với tương tác giữa trình duyệt / tác nhân người dùng hơn, trong trường hợp a không 202cho họ thấy manh mối nào (đưa cho họ 200và họ rất vui. ..).
Wrikken

1
@ user359996, chỉ cần sử dụng 200. 202là những gì nó được cho là, nhưng trong thực tế mọi người không mong đợi 202.
Pacerier

nó cần một ETA cho 200 để hữu ích trong thực tế.
Rob

Câu trả lời:


65

Nếu nó dành cho một API được xác định rõ ràng và có tài liệu, thì 202âm thanh chính xác cho những gì đang xảy ra.

Nếu nó dành cho Internet công cộng, tôi sẽ quá lo lắng về khả năng tương thích của máy khách. Tôi đã thấy rất nhiều if (status == 200)mã cứng .... Trong trường hợp đó, tôi sẽ trả lại a 200.

Ngoài ra, RFC không cho thấy việc sử dụng 202 cho yêu cầu GET là sai, trong khi nó phân biệt rõ ràng trong các mô tả mã khác (ví dụ: 200).

Yêu cầu đã được chấp nhận để xử lý, nhưng quá trình xử lý vẫn chưa hoàn tất.


15

Chúng tôi đã làm điều này cho một ứng dụng gần đây, một ứng dụng khách (ứng dụng tùy chỉnh, không phải trình duyệt) đã ĐĂNG một truy vấn và máy chủ sẽ trả về 202 với một URI cho "công việc" đang được đăng - ứng dụng khách sẽ sử dụng URI đó để thăm dò ý kiến kết quả - điều này có vẻ rất phù hợp với những gì đang được thực hiện.

Điều quan trọng nhất ở đây là ghi lại cách dịch vụ / API của bạn hoạt động và phản hồi 202 có nghĩa là gì.


+1 Cảm ơn vì bình luận của bạn. Điểm tốt về tài liệu. Nhưng vui lòng lưu ý các chỉnh sửa làm rõ cho câu hỏi của tôi (tìm kiếm "nhà máy").
user359996

Chà, bạn có thể bỏ qua URI đó trong phản hồi nếu bạn chỉ muốn thăm dò cùng một URI mà bạn thực sự yêu cầu. (Chỉ cần ghi lại cách điều này sẽ hoạt động :-))
không có

Ý kiến ​​hay, nhưng hãy nhớ rằng tôi muốn lưu vào bộ nhớ đệm, vì vậy không có ĐĂNG. Hơn nữa, URI chỉ định tài nguyên chứ không phải một phương thức. Tôi đang sử dụng phương pháp RESTful chứ không phải RPC (xin lỗi, một hạn chế không xác định khác - lỗi của tôi).
user359996

Nói một cách chính xác, "RESTful", tôi thực sự có nghĩa là "hướng tài nguyên", về mặt kỹ thuật, nó nhiều hơn một chút so với những gì được chỉ định bởi các ràng buộc REST.
user359996

12

Từ những gì tôi có thể nhớ lại - GET được cho là trả về một tài nguyên mà không cần sửa đổi máy chủ. Có thể hoạt động sẽ được ghi lại hoặc có bạn, nhưng yêu cầu phải được chạy lại với cùng một kết quả.

Mặt khác, POST là một yêu cầu thay đổi trạng thái của một thứ gì đó trên máy chủ. Chèn bản ghi, xóa bản ghi, chạy một công việc, những thứ tương tự. 202 sẽ thích hợp cho một POST đã trả về nhưng chưa hoàn thành, nhưng không thực sự là một yêu cầu GET.

Tất cả đều rất thuần khiết và không được thực hành tốt trong tự nhiên, vì vậy bạn có thể an toàn bằng cách trả lại 202. GET sẽ trả về 200. POST có thể trả về 200 nếu hoàn thành hoặc 202 nếu chưa hoàn thành.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html


4
Suy nghĩ rất tốt nhưng tôi không chắc liệu nó có áp dụng ở đây hay không: Theo những gì OP nói, đây có vẻ là một yêu cầu GET thích hợp (trong đó nó không thay đổi bất kỳ điều gì trên máy chủ), chỉ mất nhiều thời gian hơn để tính toán và trường hợp đó, sẽ được tìm nạp vào một thời điểm khác. Có thể OP có thể đưa ra một nhận xét có thẩm quyền. Nó dành cho một API nên bạn có thể trở thành "thuần khiết" vì lợi ích của một giao diện sạch sẽ
Pekka

Ồ, chạm vào pekka. Bạn nói đúng, GET là con đường để đi. Và tôi không nghĩ rằng HTTP spc thực sự đã tính đến GET chưa sẵn sàng. Vì vậy, anh ấy có thể đi theo một trong hai cách
Dlongnecker

7
(Bây giờ-không liên quan) nhận xét có thẩm quyền: Có, tôi xem đây là ý tưởng. Tài nguyên không được sửa đổi cũng như không được tạo ra, đúng hơn là sự trình bày của nó vẫn chưa được tính toán.
user359996

1
Do đâu mà nó nói vậy? Ngoài ra, nếu tôi trả lại 200, khách hàng sẽ mong đợi một đại diện đã được trả lại, nhưng nó đã không.
user359996

1
Tôi lấy lại nó. Có vẻ như 202 không tương ứng với chỉ GET hoặc POST. Chỉ suy nghĩ của tôi khi tôi xem xét giao thức đã khiến tôi nghĩ rằng 202 chỉ tồn tại cho các yêu cầu GET. 202 sẽ ổn cho mục đích của bạn.
Dlongnecker

0

Trong trường hợp một tài nguyên được cho là có đại diện của một thực thể được chỉ định rõ ràng bằng ID (trái ngược với tài nguyên "nhà máy", như được mô tả trong câu hỏi), tôi khuyên bạn nên sử dụng phương pháp GET và, trong một tình huống khi thực thể / đại diện không khả dụng do lười tạo hoặc bất kỳ tình huống tạm thời nào khác, hãy sử dụng mã phản hồi Dịch vụ Không khả dụng 503 thích hợp hơn và thực sự được thiết kế cho các tình huống như thế này.

Có thể tìm thấy lý do cho điều này trong RFCs cho chính HTTP (vui lòng xác minh mô tả của mã phản hồi 503), cũng như trên nhiều tài nguyên khác.

Vui lòng so sánh với mã trạng thái HTTP cho các trang tạm thời không khả dụng . Mặc dù câu hỏi đó là về một trường hợp sử dụng khác, nhưng nó thực sự liên quan đến cùng một tính năng của HTTP.

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.