Làm cách nào để tôi chọn mã trạng thái HTTP trong API REST cho chưa được thử, hãy thử lại sau đó? [đóng cửa]


152

Tôi đang phát triển API RESTful trong đó http://server/thingyapi/thingyblob/1234trả về tệp (còn gọi là "blob") được liên kết với điều # 1234 để tải xuống. Nhưng nó có thể là yêu cầu được thực hiện tại một thời điểm tập tin không tồn tại trong máy chủ nhưng chắc chắn sẽ có sẵn sau đó. Có một quy trình hàng loạt trong máy chủ tạo ra tất cả các đốm màu cho tất cả các điều. Thingy 1234 đã tồn tại và dữ liệu của nó, ngoài blob, đã có sẵn. Máy chủ chưa tạo ra blob 1234.

Tôi không muốn trả lại 404; đó là cho những điều không tồn tại. Đây là một điều tồn tại, nhưng blob của nó chưa được tạo ra. Giống như một video YouTube đang "xử lý". Tôi không nghĩ mã chuyển hướng cũng sẽ phù hợp; không có URL "khác" để thử.

Mã trạng thái HTTP chính xác để trả về trong trường hợp như vậy là gì?



7
Đầu tiên, nếu 1234 điều chưa có bất kỳ đại diện nào có khả năng GET, thì theo nghĩa nào thì nó tồn tại dưới dạng tài nguyên (theo quan điểm của khách hàng)? Thực tế là, bên trong máy chủ có một công việc được xếp hàng để tạo 1234, dường như không ngụ ý rằng tài nguyên 1234 tồn tại. Thứ hai, khách hàng đã lấy URI ở đâu ... / thingyblob / 1234? Máy chủ có lẽ không nên cung cấp URI đó cho máy khách cho đến khi tài nguyên thực sự có khả năng NHẬN.
Andy Dennie

1
Một điều có các thuộc tính khác có giá trị khác ngoài blob. Đó chỉ là blob cần có thời gian để tạo ra. Khách hàng có được những thứ đó, ví dụ: máy chủ / thingyapi / thingy / 1234
JCCyC

10
Tiêu chuẩn HTTP cung cấp hướng dẫn về việc sử dụng mã trạng thái nào cho tình huống nào. Câu hỏi này do đó không thực sự chủ yếu dựa trên ý kiến .
Raedwald

2
Làm thế nào về 204"Không có nội dung"? Được chỉ ra rằng máy chủ đã xử lý thành công yêu cầu và không trả lại bất kỳ nội dung nào [tại thời điểm này].
Timo

Câu trả lời:


77

Tôi đề nghị 202 - Accepted. Từ tài liệu :

Yêu cầu đã được chấp nhận để xử lý, nhưng việc xử lý chưa được hoàn thành. [...] Mục đích của nó là cho phép một máy chủ chấp nhận yêu cầu cho một quy trình khác (có lẽ là quy trình hướng theo đợt chỉ được chạy một lần mỗi ngày)


62
-1: Điều này sẽ có ý nghĩa đối với yêu cầu khởi tạo quy trình cuối cùng tạo ra "điều # 1234", nhưng không phải cho yêu cầu GET được đưa ra sau đó cho chính "điều # 1234". Cụ thể, một 202 gợi ý rằng do kết quả của yêu cầu GET, dịch vụ sẽ gửi dữ liệu cho "thingy # 1234" vào một thời điểm sau. Điều này chỉ đơn giản là không chính xác.
Sam Harwell

7
Nó cũng cho biết: "Thực thể được trả về với phản hồi này NÊN bao gồm một dấu hiệu về trạng thái hiện tại của yêu cầu và một con trỏ tới trình theo dõi trạng thái hoặc một số ước tính khi nào người dùng có thể mong đợi yêu cầu được thực hiện.", Vì vậy đây sẽ là một cách tốt để cho khách hàng biết rằng blob chưa sẵn sàng và là cách để biết khi nào nó sẵn sàng.
Rémy Lebeau

3
Tôi sẽ lập luận rằng "được chấp nhận để xử lý" chỉ ra rằng bạn đang lưu yêu cầu được xử lý sau. Nếu nó chỉ bị bỏ qua, bạn nên trả lại mã 4xx hoặc 5xx để cho khách hàng biết rằng họ có thể muốn thử lại.
Lu-ca

3
102 (xử lý) dường như cũng là một lựa chọn hợp lý đôi khi mặc dù nó nằm trong thông số webdav.
akostadinov

2
Không thể không đồng ý nhiều hơn với câu trả lời này. Máy chủ sẽ không trả lại bất cứ điều gì hoặc dự định (không thực hiện bất kỳ xử lý nào vì yêu cầu này - điều mà dù sao nó cũng không nên cho một GET). Như vậy, tài nguyên trong một số thời trang không có sẵn cho khách hàng. Điều này nên được coi là một lỗi để không có mã 2XX nào phù hợp. Một cái gì đó trong không gian 4XX hoặc 5XX. Yêu cầu chưa "được chấp nhận để xử lý" , yêu cầu này trong thực tế đang bị loại bỏ
Adam

52

"Vấn đề", chẳng hạn như, nằm ở phía máy chủ: máy khách đã thực hiện một yêu cầu được hình thành tốt, nhưng máy chủ không thể đáp ứng. Vì vậy, tôi nghiêng về "Lỗi máy chủ", mã trạng thái 5xx.

Quoth RFC 7231 (tiêu chuẩn HTTP hiện tại, đã nhấn mạnh thêm):

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 hoặc không có khả năng thực hiện phương thức được yêu cầu . Ngoại trừ khi trả lời yêu cầu CHÍNH, máy chủ NÊN gửi một đại diện có giải thích về tình huống lỗi và cho dù đó là tình trạng tạm thời hay vĩnh viễn.

Ghi chú

  • "bị lỗi hoặc không có khả năng thực hiện yêu cầu": mặc dù tiêu đề "Lỗi máy chủ" của họ, chúng không chỉ dành cho lỗi máy chủ.
  • " tạm thời hoặc vĩnh viễn": các mã này phù hợp với các tài nguyên tạm thời không có sẵn, như của bạn.

Trong số các mã có sẵn, tôi muốn nói 503, "Dịch vụ không khả dụng" là phù hợp nhất:

Mã trạng thái 503 (Dịch vụ không khả dụng) cho biết rằng 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ẽ được giảm bớt sau một số chậm trễ. Máy chủ CÓ THỂ gửi trường tiêu đề Thử lại sau ... để đề xuất một lượng thời gian thích hợp để khách hàng chờ đợi trước khi thử lại yêu cầu.

Ghi chú:

  • "Có khả năng được giảm bớt sau một số chậm trễ": đúng với trường hợp của bạn.
  • "Quá tải tạm thời": không đúng về mặt giáo dục cho trường hợp của bạn. Nhưng, có thể tranh cãi, máy chủ của bạn nhanh hơn nhiều, việc xử lý hàng loạt đã được thực hiện khi khách hàng thực hiện yêu cầu, vì vậy đó một loại "quá tải": máy khách đang yêu cầu tài nguyên nhanh hơn máy chủ có thể thực hiện chúng có sẵn.
  • Thử lại là phù hợp với dịch vụ của bạn, vì vậy câu trả lời của bạn phải bao gồm một Retry-Aftergiá trị. Bạn có thể cung cấp dưới dạng giá trị thời gian hoàn thành ước tính của lần thực hiện tiếp theo của quy trình lô hoặc khoảng thời gian thực hiện của quy trình lô.

Xác định mã trạng thái 5xx của riêng bạn (ví dụ 591), mặc dù được phép , sẽ có ngữ nghĩa sai:

khách hàng PHẢI hiểu lớp của bất kỳ mã trạng thái nào, như được chỉ ra bởi chữ số đầu tiên và coi mã trạng thái không được nhận dạng là tương đương với mã trạng thái x00 của lớp đó

Khách hàng sẽ coi mã trạng thái của riêng bạn là 500, "Lỗi máy chủ nội bộ" , điều này không đúng.


2
Tôi không thấy nó tốt hơn 202: benramsey.com/blog/2008/04/ từ
JCCyC

4
@JCCyC blog của bạn tạo ra một trường hợp tốt để trả lại 202 để đáp ứng yêu cầu tạo một cái gì đó (POST hoặc PUT). Câu hỏi dường như được hỏi về những gì cần trả lại cho một GET.
Raedwald

@JCCyC nó có thể được coi là một sắc thái khác nhau của sự không sẵn sàng: hãy tưởng tượng một ajax cho nguồn tài nguyên đó, bạn thích 202 là trạng thái thành công hay 503 là trạng thái lỗi? để bạn có thể thấy ý nghĩa mà bạn thích ngầm trong bối cảnh phản ứng của ứng dụng của bạn đối với phản hồi
rloth

Ngoài ra, tôi thích khía cạnh thực tế của "Thử lại sau" rất phù hợp với điều gì đó "chưa sẵn sàng"
rloth

1
Lưu ý: "Thử lại sau" cũng có thể đi với 307 - TEMPORARY REDIRECTđiều đó là tốt nếu bạn muốn buộc phía khách hàng phải đợi ở nơi khác trong khi nguồn tài nguyên của bạn đang "sẵn sàng"
rloth

28

Tôi nghĩ rằng 423 - Khóa có thể được sử dụng cho mục đích này:

Mã trạng thái 423 (Đã khóa) có nghĩa là tài nguyên nguồn hoặc đích của phương thức bị khóa. Phản hồi này NÊN chứa một điều kiện tiên quyết hoặc mã hậu điều kiện thích hợp, chẳng hạn như 'khóa gửi mã thông báo' hoặc 'không xung đột khóa'.


1
Câu trả lời tuyệt vời! Tôi tự hỏi tại sao nó không có nhiều upvote.
lex82

10
Có lẽ bởi vì nó là mã HTTP WebDAV?
Stephan L

1
Từ akka-http có StatusCode RetryWith = reg (c (449) ("Thử lại với", "Yêu cầu nên được thử lại sau khi thực hiện hành động thích hợp.")) Trong đó hành động sẽ được chờ và thử lại
ozma

2
Theo nhiều cách tôi đồng ý với điều này. Tôi có một tình huống tương tự (trong trường hợp của tôi là tìm kiếm từ một chỉ mục có thể chưa được xác định). Về mặt ngữ nghĩa, tôi nghĩ điều này là chính xác. Tuy nhiên, RFC cho 423 nói rằng "Phản hồi này NÊN chứa một điều kiện tiên quyết hoặc mã hậu điều kiện thích hợp, chẳng hạn như 'khóa-token-gửi' hoặc 'không xung đột khóa'." Không chắc chắn làm thế nào để áp dụng điều đó ở đây. Và cá nhân tôi sẽ đi với 409 Xung đột, nhưng điều đó đã bị hạ thấp mà không có ý kiến ​​- không biết tại sao?
Adam

22

Tôi không muốn trả lại 404; đó là cho những điều không tồn tại.

URL không tương ứng với một yêu cầu cho một điều.

http://server/thingyapi/thingyblob/1234

Khách hàng đang yêu cầu một thingyblob, không tồn tại. Nếu nó tồn tại, bạn sẽ đưa nó cho họ.

404.


1
Tôi rất vui vì ai đó đã nói điều này! Tôi không thể tin rằng có rất nhiều người nghĩ rằng đó 503là một phản ứng thích hợp. Không đề cập đến một số gợi ý lạ khác.
Jason Desrosiers

Mặc dù tôi đồng ý rằng 404 là phản hồi phù hợp nhất ở đây, nhưng nó không trả lời câu hỏi của OP làm thế nào để chỉ ra khi nào có sẵn :-). Tôi nghĩ rằng trường Retry-After có vẻ là ứng cử viên tốt nhất nhưng nó chỉ có thể được sử dụng chính thức cho mã 503 và 3xx. @Jason: Tôi nghĩ điều đó giải thích một số gợi ý lạ.
Ron Deijkers

Tôi nghĩ rằng đây là câu trả lời tốt nhất. Bạn được phép trả lại một cơ thể trong một phản hồi 404. Cơ thể có thể chỉ ra rằng điều đó sẽ có sẵn vào một ngày sau đó. Hoặc sử dụng tiêu đề Retry-After là tốt. Các tiêu chuẩn cần phải được kéo dài một chút ở đây vì nó không bao gồm trường hợp này độc đáo.
Thế chiến.

4
Mọi người đã trở nên quá thích nghi với trang 404 có nghĩa là không tìm thấy rằng họ không thể phân tách một cách hợp lý điều đó khi trong bối cảnh của API.
Người đàn ông Muffin

1
Đây là sooooo 404. Thingyblob chưa tồn tại, hoặc bao giờ .. Đối với http, nó không phù hợp nếu nó sẽ có sẵn. Tại thời điểm nó không tồn tại và 404. Khi nó có sẵn là một vấn đề khác, có thể được giải quyết bằng cách đẩy một mesage từ máy chủ sang máy khách sayin thingyblob: 1234 có sẵn. Thực hiện một lần nữa và voila ..
100r

21

Một lựa chọn khác : 503 - Service Unavailable.


5
Theo W3C, đó không phải là điều bạn muốn nói với khách hàng (mặc dù điều đó có nghĩa là "trở lại" theo cách nào đó): "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ì máy chủ. Ý nghĩa là Đây là một điều kiện tạm thời sẽ được giảm bớt sau một số độ trễ. Nếu biết, độ dài của độ trễ có thể được chỉ định trong tiêu đề Retry-After. Nếu không có Retry-After được đưa ra, khách hàng NÊN xử lý phản hồi như đối với 500 phản hồi. "
skalee

4
Dịch vụ không có sẵn, dịch vụ có sẵn nhưng quá trình xử lý chưa hoàn tất. Vì vậy, 503 có lẽ không phải là một ý tưởng tốt.
Ishtiaque Khan

17

Vì tài nguyên của bạn chưa sẵn sàng, nên bạn có thể biết khi nào (khoảng) nó sẽ có sẵn và khi nào khách hàng có thể thử lại yêu cầu của mình. Điều này có nghĩa là bạn có thể muốn sử dụng tiêu đề Retry-After . Tiêu đề này hợp lệ với 503 (Dịch vụ không khả dụng), có nghĩa là toàn bộ trang web không hoạt động để bảo trì và phản hồi 3xx (Chuyển hướng).

Theo tôi, 302 (Đã tìm thấy) với tiêu đề Retry-After sẽ là tùy chọn tốt nhất, nhưng tôi không chắc liệu trường Vị trí của tiêu đề phản hồi có thể bằng với url yêu cầu hay không. Dù sao đó cũng là chuyển hướng tròn.


3
Ngay cả khi được cho phép, nếu ứng dụng khách chưa triển khai hỗ trợ cho tiêu đề Retry-After thì Chuyển hướng 3xx đến cùng một trang cuối cùng có thể kết thúc bằng 503 ... (dĩ nhiên là có tiêu đề Retry-After)
Ron Deijker

1
Retry-After cũng hợp lệ với HTTP 429 "Quá nhiều yêu cầu", được thêm bởi RFC 6585 (tháng 4 năm 2012). Điều này có thể phù hợp nếu lý do tài nguyên chưa sẵn sàng là máy khách đã cung cấp cho máy chủ quá nhiều việc phải làm.
Silas S. Brown

8

409 Xung đột

Chỉ ra rằng yêu cầu không thể được xử lý do xung đột trong yêu cầu, chẳng hạn như xung đột chỉnh sửa trong trường hợp có nhiều cập nhật. [Nguồn Wikipedia.]

Điều này có thể thích hợp.

Nếu bạn không thể thực hiện yêu cầu bằng cách trả lại dữ liệu - thì đó không phải là thành công. Tôi nghĩ 202 cho thấy máy chủ đã xếp hàng yêu cầu và nó sẽ thực hiện yêu cầu sau. Nhưng trong trường hợp của bạn, yêu cầu là cho dữ liệu bây giờ và đã thất bại. Nếu bạn thử lại sau đó là một yêu cầu khác.

Tôi nghĩ rằng bạn có một cuộc xung đột .. bạn muốn dữ liệu .. nhưng nó đang được chỉnh sửa / cập nhật. Đây cũng là trường hợp nếu Thingy1234 đã tồn tại và đã được tải xuống thành công trước đó, nhưng bây giờ trong quá trình chỉnh sửa không có sẵn trong khi quá trình chỉnh sửa đang diễn ra.


2
Không chắc chắn tại sao điều này đã được bỏ phiếu xuống. Có vẻ như câu trả lời đúng cho tôi. Từ RFC: "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. "Bạn đã yêu cầu tài nguyên mà máy chủ không thể trả về vì máy chủ đang trong quá trình cập nhật tài nguyên đó - tức là do trạng thái hiện tại của tài nguyên. Khách hàng có thể giải quyết vấn đề này bằng cách chờ đợi và gửi lại
Adam

1
@Adam Tôi nghĩ rằng hàm ý trong "người dùng có thể giải quyết được xung đột" là một cái gì đó về việc gửi lại sẽ khác, ngoài việc chỉ chờ đợi.
Nhà phát triển toàn diện

3

501 - Không được thực hiện

Chính xác như cách nó nghe. Một tính năng chưa được triển khai, nhưng ngụ ý tính khả dụng trong tương lai.

Đây là một liên kết đến một bản tóm tắt các lỗi 5xx .


4
Đối với câu hỏi này có vẻ như chính tính năng này tồn tại, nhưng mục được yêu cầu thì không.
Lu-ca

Mô tả của @Luke 501 từ liên kết trong câu trả lời của tôi, '... nó thiếu khả năng thực hiện yêu cầu. Thông thường, điều này hàm ý sự sẵn có trong tương lai '. Điều này đáp ứng chính xác những gì OP yêu cầu. Bất kể dữ liệu có trên máy chủ hoặc DB của anh ta hay không. Kết quả cuối cùng là hiện tại nó không thể truy cập được thông qua API. Do đó, API không thể thực hiện yêu cầu, nhưng muốn ngụ ý rằng nó sẽ có sẵn trong tương lai thông qua mã http.
Dan
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.