Ví dụ: bạn chạy yêu cầu GET cho users/9
nhưng không có người dùng nào có id # 9. Mã phản hồi tốt nhất là gì?
- 200 OK
- 202 được chấp nhận
- 204 Không có nội dung
- 400 yêu cầu xấu
- 404 không tìm thấy
Ví dụ: bạn chạy yêu cầu GET cho users/9
nhưng không có người dùng nào có id # 9. Mã phản hồi tốt nhất là gì?
Câu trả lời:
TL; DR: Sử dụng 404
Xem Blog này . Nó giải thích nó rất tốt.
Tóm tắt ý kiến của blog về 204
:
204 No Content
không thực sự hữu ích như mã phản hồi cho trình duyệt (mặc dù theo trình duyệt thông số kỹ thuật HTTP, bạn cần phải hiểu mã này là 'không thay đổi mã phản hồi của chế độ xem).204 No Content
là tuy nhiên, rất hữu ích cho các dịch vụ web ajax mà có thể muốn biết sự thành công mà không cần phải quay trở lại một cái gì đó. (Đặc biệt trong những trường hợp như DELETE
hoặc POST
không yêu cầu phản hồi).Câu trả lời, do đó, cho câu hỏi của bạn là sử dụng 404
trong trường hợp của bạn. 204
là một mã phản hồi chuyên biệt mà bạn không nên thường xuyên quay lại trình duyệt để phản hồi lại GET
.
Các mã phản hồi khác thậm chí ít phù hợp hơn 204
và 404
:
200
nên được trả lại với cơ thể của bất cứ điều gì bạn đã tìm nạp thành công. Không phù hợp khi thực thể bạn tìm nạp không tồn tại.202
được sử dụng khi máy chủ đã bắt đầu hoạt động trên một đối tượng nhưng đối tượng chưa hoàn toàn sẵn sàng. Chắc chắn không phải là trường hợp ở đây. Bạn chưa bắt đầu, bạn cũng sẽ không bắt đầu, xây dựng người dùng 9 để đáp ứng GET
yêu cầu. Điều đó phá vỡ tất cả các loại quy tắc.400
được sử dụng để đáp ứng yêu cầu HTTP được định dạng kém (ví dụ: các tiêu đề http không đúng định dạng, các phân đoạn được đặt hàng không chính xác, v.v.). Điều này gần như chắc chắn sẽ được xử lý bởi bất kỳ khuôn khổ nào bạn đang sử dụng. Bạn không cần phải giải quyết vấn đề này trừ khi bạn viết máy chủ của riêng mình từ đầu. Chỉnh sửa : RFC mới hơn hiện cho phép 400 được sử dụng cho các yêu cầu không hợp lệ về mặt ngữ nghĩa.Mô tả của Wikipedia về các mã trạng thái HTTP đặc biệt hữu ích. Bạn cũng có thể xem các định nghĩa trong tài liệu HTTP / 1.1 RFC2616 tại www.w3.org
204
mã phản hồi (Không có nội dung).
/badurl
hoặc /user/9
khi người dùng đó không tồn tại. Nhà phát triển có thể giúp đỡ bằng cách thêm cụm từ lý do tốt hơn 'Không tìm thấy', nhưng không bắt buộc.
The server has not found anything matching the Request-URI
. Trên thực tế, máy chủ ứng dụng / web đã tìm thấy một HÀNH ĐỘNG phù hợp với URI yêu cầu, mặc dù máy chủ db thì không. Tuy nhiên, nó cũng nói This status code is commonly used when [...] no other response is applicable
, vì vậy tôi nghĩ rằng việc xác nhận phần nào việc sử dụng nó (ngay cả khi tôi không đồng ý với / thích nó).
Tôi cực lực phản đối 404 ủng hộ 204 hoặc 200 với dữ liệu trống. Hoặc ít nhất một người nên sử dụng một thực thể phản hồi với 404.
Yêu cầu đã được nhận và xử lý đúng cách - nó đã kích hoạt mã ứng dụng trên máy chủ, do đó người ta không thể thực sự nói rằng đó là lỗi máy khách và do đó toàn bộ lớp mã lỗi máy khách (4xx) không phù hợp.
Quan trọng hơn, 404 có thể xảy ra vì một số lý do kỹ thuật. Ví dụ: ứng dụng đang tạm thời bị vô hiệu hóa hoặc gỡ cài đặt trên máy chủ, các sự cố kết nối proxy và không có gì. Do đó, khách hàng không thể phân biệt giữa 404 có nghĩa là "tập kết quả trống" và 404 có nghĩa là "không thể tìm thấy dịch vụ, thử lại sau".
Điều này có thể gây tử vong: Hãy tưởng tượng một dịch vụ kế toán trong công ty của bạn liệt kê tất cả các nhân viên là do tiền thưởng hàng năm. Thật không may, một lần khi nó được gọi là nó trả về 404. Điều đó có nghĩa là không có ai là do tiền thưởng, hay ứng dụng hiện đang ngừng hoạt động để triển khai mới?
-> Đối với các ứng dụng quan tâm đến chất lượng dữ liệu của họ, 404 không có thực thể phản hồi do đó không có gì đáng ngại.
Ngoài ra, nhiều khung khách hàng trả lời 404 bằng cách đưa ra một ngoại lệ mà không có câu hỏi nào được hỏi thêm. Điều này buộc nhà phát triển ứng dụng khách phải nắm bắt ngoại lệ đó, đánh giá nó và sau đó quyết định dựa trên việc có ghi nhật ký đó là lỗi được chọn hay không, ví dụ như một thành phần giám sát hoặc có nên bỏ qua nó hay không. Điều đó cũng không đẹp đối với tôi.
Ưu điểm của 404 trên 204 là nó có thể trả về một thực thể phản hồi có thể chứa một số thông tin về lý do tại sao tài nguyên được yêu cầu không được tìm thấy. Nhưng nếu điều đó thực sự có liên quan, thì người ta cũng có thể xem xét sử dụng phản hồi 200 OK và thiết kế hệ thống theo cách cho phép phản hồi lỗi trong dữ liệu tải trọng. Ngoài ra, người ta có thể sử dụng tải trọng của phản hồi 404 để trả về thông tin có cấu trúc cho người gọi. Nếu anh ta nhận được ví dụ như một trang html thay vì XML hoặc JSON mà anh ta có thể phân tích cú pháp, thì đó là một chỉ báo tốt cho thấy có gì đó không ổn về mặt kỹ thuật thay vì trả lời "không có kết quả" có thể hợp lệ theo quan điểm của người gọi. Hoặc người ta có thể sử dụng tiêu đề phản hồi HTTP cho điều đó.
Tuy nhiên, tôi vẫn thích 204 hoặc 200 với phản hồi trống. Bằng cách đó, trạng thái thực hiện kỹ thuật của yêu cầu được tách ra khỏi kết quả logic của yêu cầu. 2xx có nghĩa là "thực thi kỹ thuật ok, đây là kết quả, giải quyết nó".
Tôi nghĩ rằng trong hầu hết các trường hợp, nó nên để lại cho khách hàng để quyết định xem một kết quả trống có được chấp nhận hay không. Bằng cách trả về 404 mà không có thực thể phản hồi mặc dù thực hiện kỹ thuật chính xác, khách hàng có thể quyết định coi các trường hợp là lỗi mà đơn giản là không có lỗi.
Một sự tương tự nhanh khác: Trả về 404 cho "không tìm thấy kết quả" giống như ném một DatabaseConnectionException nếu một truy vấn SQL không có kết quả. Nó có thể hoàn thành công việc, nhưng có rất nhiều nguyên nhân kỹ thuật có thể gây ra ngoại lệ tương tự mà sau đó sẽ bị nhầm lẫn với kết quả hợp lệ.
503 Service Unavailable
.
/users
tuyến đường, nhưng /users/9
, tức là "Người dùng được gọi là số 9"), do đó, so sánh 'tập kết quả trống rỗng' của bạn không có ý nghĩa. 404 có nghĩa là đối tượng không tồn tại.
Lúc đầu, tôi nghĩ rằng 204 sẽ có ý nghĩa, nhưng sau các cuộc thảo luận, tôi tin rằng 404 là phản hồi chính xác duy nhất. Hãy xem xét các dữ liệu sau:
Người dùng: John, Peter
METHOD URL STATUS RESPONSE
GET /users 200 [John, Peter]
GET /users/john 200 John
GET /users/kyle 404 Not found
GET /users?name=kyle` 200 []
DELETE /users/john 204 No Content
Một số nền tảng:
tìm kiếm trả về một mảng, nó không có bất kỳ kết quả khớp nào nhưng nó có nội dung: một mảng trống .
Tất nhiên 404 được biết đến nhiều nhất với các url không được máy chủ yêu cầu hỗ trợ, nhưng trên thực tế, một tài nguyên bị thiếu là như nhau.
Mặc dù /users/:name
được khớp với users/kyle
, người dùng Kyle không có sẵn tài nguyên nên 404 vẫn được áp dụng. Đó không phải là một truy vấn tìm kiếm, nó là một tham chiếu trực tiếp bởi một url động , vì vậy nó là 404.
Dù sao, hai xu của tôi :)
Nếu nó dự kiến rằng tài nguyên tồn tại, nhưng nó có thể trống, tôi sẽ lập luận rằng có thể dễ dàng hơn để có được 200 OK với một đại diện chỉ ra rằng điều đó là trống rỗng.
Vì vậy, tôi muốn có / mọi thứ trả lại 200 OK với {"Vật phẩm": []} so với 204 không có gì cả, bởi vì theo cách này, một bộ sưu tập có 0 vật phẩm có thể được coi giống như một bộ sưu tập với một hoặc Thêm mục trong đó.
Tôi chỉ để lại 204 Không có nội dung cho PUT và XÓA, trong đó có thể là trường hợp thực sự không có đại diện hữu ích.
Trong trường hợp / điều / 9 thực sự không tồn tại, 404 là phù hợp.
customers/1/addressbook
, cách RPC là gọi một điểm cuối giống như GetCustomerAddressBook
và nhận dữ liệu hoặc về cơ bản là null và không phải lo lắng quá nhiều về sự phức tạp của HTTP. Có những ưu và nhược điểm cho cả hai.
Trong các dự án trước đây, tôi đã sử dụng 404. Nếu không có người dùng 9, thì đối tượng không được tìm thấy. Do đó 404 Không tìm thấy là phù hợp.
Đối với đối tượng tồn tại, nhưng không có dữ liệu, 204 Không có nội dung nào phù hợp. Tôi nghĩ rằng trong trường hợp của bạn, đối tượng không tồn tại mặc dù.
Theo bài đăng trên w3 ,
200 OK
Yêu cầu đã thành công. Thông tin được trả về với phản hồi phụ thuộc vào phương thức được sử dụng trong yêu cầu
202 được chấp nhận
Yêu cầu đã được chấp nhận để xử lý, nhưng việc xử lý chưa được hoàn thành.
204 Không có nội dung
Máy chủ đã hoàn thành yêu cầu nhưng không cần trả về một thực thể và có thể muốn trả về các thông số được cập nhật.
400 yêu cầu xấu
Máy chủ không thể hiểu được yêu cầu do cú pháp không đúng. Khách hàng KHÔNG NÊN lặp lại yêu cầu mà không sửa đổi
401 trái phép
Yêu cầu yêu cầu xác thực người dùng. Phản hồi PHẢI bao gồm trường tiêu đề WWW-xác thực
404 không tìm thấy
Máy chủ không tìm thấy bất cứ thứ gì khớp với URI yêu cầu. Không có dấu hiệu nào được đưa ra cho dù tình trạng này là tạm thời hay vĩnh viễn
204 No Content
khi không tìm thấy kết quả. Không 404
, nó có kết quả cho bạn, nhưng nó không có nội dung ..
Để tóm tắt hoặc đơn giản hóa,
2xx: Dữ liệu tùy chọn: URI được hình thành tốt: Tiêu chí không phải là một phần của URI: Nếu tiêu chí là tùy chọn có thể được chỉ định trong @RequestBody và @RequestParam sẽ dẫn đến 2xx. Ví dụ: lọc theo tên / trạng thái
4xx: Dữ liệu dự kiến: URI không được hình thành tốt: Tiêu chí là một phần của URI: Nếu tiêu chí là bắt buộc chỉ có thể được chỉ định trong @PathVariable thì nó sẽ dẫn đến 4xx. Ví dụ: tra cứu theo id duy nhất.
Do đó, đối với tình huống được hỏi: "người dùng / 9" sẽ là 4xx (có thể là 404) Nhưng đối với "người dùng? Name = superman" phải là 2xx (có thể là 204)
Có hai câu hỏi được đặt ra. Một trong tiêu đề và một trong ví dụ. Tôi nghĩ rằng điều này đã một phần dẫn đến số lượng tranh chấp về phản ứng nào là phù hợp.
Tiêu đề câu hỏi hỏi về dữ liệu trống. Dữ liệu trống vẫn là dữ liệu nhưng không giống như không có dữ liệu. Vì vậy, điều này gợi ý yêu cầu một tập kết quả, tức là một danh sách, có lẽ từ /users
. Nếu một danh sách trống thì nó vẫn là một danh sách do đó 204 (Không có nội dung) là phù hợp nhất. Bạn vừa yêu cầu một danh sách người dùng và được cung cấp một danh sách, điều đó xảy ra là không có nội dung.
Ví dụ được cung cấp thay vì hỏi về một đối tượng cụ thể, một người dùng , /users/9
. Nếu không tìm thấy người dùng số 9 thì không có đối tượng người dùng nào được trả về. Bạn đã yêu cầu một tài nguyên cụ thể (một đối tượng người dùng) và không được cung cấp bởi vì nó không được tìm thấy, vì vậy 404 là phù hợp.
Tôi nghĩ rằng cách để giải quyết vấn đề này là nếu bạn có thể sử dụng phản hồi theo cách bạn mong đợi mà không cần thêm bất kỳ tuyên bố điều kiện nào, sau đó sử dụng 204 nếu không sử dụng 404.
Trong các ví dụ của tôi, tôi có thể lặp lại một danh sách trống mà không cần kiểm tra xem nó có nội dung không, nhưng tôi không thể hiển thị dữ liệu đối tượng người dùng trên một đối tượng null mà không phá vỡ một cái gì đó hoặc thêm một kiểm tra để xem nó có rỗng không.
Tất nhiên bạn có thể trả về một đối tượng bằng cách sử dụng mẫu đối tượng null nếu phù hợp với nhu cầu của bạn nhưng đó là một cuộc thảo luận cho một luồng khác.
Sau khi xem xét câu hỏi, bạn không nên sử dụng 404
tại sao?
Dựa trên RFC 7231 , mã trạng thái chính xác là204
Trong phần anwsers ở trên tôi nhận thấy 1 lỗi nhỏ:
1.- tài nguyên là: /users
2.- /users/8
không phải là tài nguyên, đây là: tài nguyên /users
có tham số tuyến đường 8
, người tiêu dùng có thể không nhận thấy nó và không biết sự khác biệt, nhưng nhà xuất bản làm và phải biết điều này! ... vì vậy anh ta phải trả lời chính xác cho người tiêu dùng. giai đoạn = Stage.
vì thế:
Dựa trên RFC: 404 không chính xác vì các tài nguyên /users
được tìm thấy, nhưng logic được thực thi bằng tham số 8
không tìm thấy bất kỳ content
để trả về dưới dạng phản hồi, vì vậy câu trả lời đúng là:204
Điểm chính ở đây là: 404
thậm chí không tìm thấy tài nguyên để xử lý logic bên trong
204
là: Tôi đã tìm thấy tài nguyên, logic đã được thực thi nhưng tôi không tìm thấy bất kỳ dữ liệu nào sử dụng tiêu chí của bạn được đưa ra trong tham số tuyến đường vì vậy tôi không thể trả lại bất cứ điều gì cho bạn. Tôi xin lỗi, xác minh tiêu chí của bạn và gọi lại cho tôi.
200
: ok tôi đã tìm thấy tài nguyên, logic đã được thực thi (ngay cả khi tôi không bị buộc phải trả lại bất cứ thứ gì) lấy cái này và sử dụng nó theo ý muốn của bạn.
205
: (tùy chọn tốt nhất của phản hồi GET) Tôi đã tìm thấy tài nguyên, logic đã được thực thi, tôi có một số nội dung cho bạn, sử dụng nó tốt, ồ nhân tiện nếu bạn sẽ chia sẻ điều này trong chế độ xem, hãy làm mới chế độ xem hiển thị nó
Hy vọng nó giúp.
Điều mà các câu trả lời hiện tại không giải thích được là nó tạo ra sự khác biệt cho dù bạn sử dụng tham số đường dẫn hay tham số truy vấn.
/users/9
, phản hồi nên là 404
vì tài nguyên đó không được tìm thấy. /users/9
là tài nguyên và kết quả là đơn nguyên hoặc lỗi, nó không tồn tại. Đây không phải là một đơn nguyên./users?id=9
, phản hồi phải là 204
do tài nguyên /users
đã được tìm thấy nhưng nó không thể trả về bất kỳ dữ liệu nào. Tài nguyên /users
tồn tại và kết quả là n-ary, nó tồn tại ngay cả khi nó trống. Nếu id
là duy nhất, đây là một đơn nguyên.Việc sử dụng tham số đường dẫn hay tham số truy vấn tùy thuộc vào trường hợp sử dụng. Tôi thích các tham số đường dẫn cho các đối số bắt buộc, quy phạm hoặc xác định tham số và tham số truy vấn cho các đối số tùy chọn, không quy tắc hoặc quy kết (như phân trang, ngôn ngữ đối chiếu và nội dung). Trong API REST, tôi sẽ /users/9
không sử dụng /users?id=9
đặc biệt vì có thể lồng để lấy "hồ sơ con" như muốn /users/9/ssh-keys/0
lấy khóa ssh công khai đầu tiên hoặc /users/9/address/2
để lấy địa chỉ bưu chính thứ ba.
Tôi thích sử dụng 404. Đây là lý do:
204
giống như một void
phương pháp. Tôi sẽ không sử dụng nó cho GET
, chỉ cho POST
, PUT
và DELETE
. Tôi tạo một ngoại lệ trong trường hợp GET
các định danh là tham số truy vấn không phải là tham số đường dẫn.NoSuchElementException
, ArrayIndexOutOfBoundsException
hoặc một cái gì đó tương tự, do khách hàng sử dụng id không tồn tại, do đó, đó là lỗi của máy khách.204
có nghĩa là một nhánh bổ sung trong mã có thể tránh được. Nó phức tạp mã khách hàng, và trong một số trường hợp nó còn làm phức tạp mã máy chủ (tùy thuộc vào việc bạn sử dụng monads tổ chức / mô hình hoặc tổ chức đồng bằng / mô hình; và tôi mạnh mẽ khuyến cáo tránh xa monads tổ chức / mô hình, nó có thể dẫn đến lỗi khó chịu nơi vì của đơn vị bạn nghĩ rằng một hoạt động thành công và trả lại 200 hoặc 204 khi bạn thực sự nên trả lại một cái gì đó khác).Cuối cùng nhưng không kém phần quan trọng: Tính nhất quán
GET /users/9
PUT /users/9
và DELETE /users/9
PUT /users/9
và DELETE /users/9
đã phải quay lại 204
trong trường hợp cập nhật hoặc xóa thành công. Vậy họ nên trả lại cái gì trong trường hợp người dùng 9 không tồn tại? Không có nghĩa là có cùng một tình huống được trình bày dưới dạng các mã trạng thái khác nhau tùy thuộc vào phương thức HTTP được sử dụng.
Bên cạnh đó, không phải là một quy tắc, mà là một lý do văn hóa: Nếu 204
được sử dụng cho GET /users/9
điều tiếp theo sẽ xảy ra trong dự án là ai đó nghĩ rằng việc quay lại 204
là tốt cho các phương pháp n-ary. Và điều đó làm phức tạp mã khách hàng, vì thay vì chỉ kiểm tra 2xx
và sau đó giải mã cơ thể, giờ đây khách hàng phải kiểm tra cụ thể 204
và trong trường hợp đó bỏ qua việc giải mã cơ thể. Bud khách hàng làm gì thay thế? Tạo một mảng trống? Tại sao không có trên dây, sau đó? Nếu máy khách tạo mảng trống, 204 là một dạng nén ngu ngốc. Nếu khách hàng sử dụng null
thay thế, một hộp giun hoàn toàn khác sẽ được mở.
Twitter sử dụng 404 với thông báo lỗi tùy chỉnh như "Không tìm thấy dữ liệu".
Tham chiếu: https://developer.twitter.com/en/docs/basics/response-codes.html
204 là phù hợp hơn. Đặc biệt là khi bạn có một hệ thống cảnh báo để đảm bảo trang web của bạn được an toàn, 404 trong trường hợp này sẽ gây nhầm lẫn vì bạn không biết một số cảnh báo 404 là lỗi phụ trợ hoặc yêu cầu bình thường nhưng phản hồi trống.
Tôi muốn nói, không thực sự thích hợp. Như đã nói - ví dụ bởi @anneb, tôi cũng nghĩ rằng một phần của các vấn đề phát sinh từ việc sử dụng mã phản hồi HTTP để vận chuyển trạng thái liên quan đến dịch vụ RESTful. Bất cứ điều gì dịch vụ REST phải nói về quá trình xử lý riêng của nó phải được vận chuyển bằng các mã cụ thể REST.
Tôi tranh luận rằng, nếu máy chủ HTTP tìm thấy bất kỳ dịch vụ nào sẵn sàng trả lời yêu cầu đã được gửi, thì nó sẽ không phản hồi với HTTP 404 - cuối cùng, máy chủ đã tìm thấy thứ gì đó - trừ khi được máy chủ nói một cách rõ ràng dịch vụ xử lý yêu cầu.
Chúng ta hãy giả sử một lúc URL sau : http://example.com/service/return/test
.
404
là chính xác. Điều tương tự cũng đúng, nếu nó yêu cầu một loại dịch vụ nào đó cung cấp chính xác tệp này và dịch vụ đó nói với nó rằng không có tên nào tồn tại.Không có bất kỳ phản hồi nào từ dịch vụ yêu cầu một hành vi khác, máy chủ HTTP chỉ có thể nói 3 điều:
503
nếu dịch vụ được cho là xử lý yêu cầu không chạy hoặc phản hồi;200
mặt khác, vì máy chủ HTTP thực sự có thể đáp ứng yêu cầu - bất kể dịch vụ sẽ nói gì sau này;400
hoặc 404
để chỉ ra rằng không có dịch vụ nào như vậy (trái ngược với hiện tại nhưng ngoại tuyến) và không có gì khác được tìm thấy.Để quay trở lại câu hỏi trong tay: Tôi nghĩ rằng cách tiếp cận sạch nhất sẽ là không sử dụng HTTP bất kỳ mã phản hồi nào khác hơn là đã nói trước đó. Nếu dịch vụ có mặt và phản hồi, mã HTTP phải là 200. Phản hồi sẽ chứa trạng thái dịch vụ được trả về trong một tiêu đề riêng - ở đây, dịch vụ có thể nói
REST:EMPTY
ví dụ nếu nó được yêu cầu tìm kiếm sth. và nghiên cứu đó trở lại trống rỗng;REST:NOT FOUND
nếu nó được hỏi cụ thể cho sth. Giống như ID ID - có thể là tên tệp hoặc tài nguyên theo ID hoặc mục nhập số 24, v.v. - và tài nguyên cụ thể đó không được tìm thấy (thông thường, một tài nguyên cụ thể đã được yêu cầu và không tìm thấy);REST:INVALID
nếu bất kỳ phần nào của yêu cầu được gửi không được dịch vụ nhận ra..
Chúng ta hãy quay lại URL ở trên và kiểm tra trường hợp B nơi dịch vụ chỉ ra cho máy chủ HTTP rằng nó không tự xử lý yêu cầu này mà chuyển nó đến SERVICE
. HTTP chỉ cung cấp những gì nó được trao lại SERVICE
, nó không biết gì về return/test
phần được xử lý SERVICE
. Nếu dịch vụ đó đang chạy, HTTP sẽ quay trở lại 200
vì nó thực sự đã tìm thấy thứ gì đó để xử lý yêu cầu.
Trạng thái được trả về bởi SERVICE
(và như đã nói ở trên, muốn thấy trong một tiêu đề riêng) phụ thuộc vào hành động nào thực sự được mong đợi:
return/test
yêu cầu một tài nguyên cụ thể: nếu nó tồn tại, trả lại nó với trạng thái REST:FOUND
; nếu tài nguyên đó không tồn tại, trả lại REST:NOT FOUND
; điều này có thể được mở rộng để trở lại REST:GONE
nếu chúng ta biết nó đã tồn tại và sẽ không quay trở lại, và REST:MOVED
nếu chúng ta biết nó đã biến mấtreturn/test
được coi là một hoạt động giống như tìm kiếm hoặc bộ lọc: nếu tập kết quả trống, trả về một tập hợp trống trong loại được yêu cầu và trạng thái REST:EMPTY
; một tập hợp kết quả theo loại được yêu cầu và trạng tháiREST:SUCCESS
return/test
không phải là một hoạt động được ghi SERVICE
lại bằng cách : return REST:ERROR
nếu nó hoàn toàn sai (ví dụ như một lỗi đánh máy retrun/test
), hoặc REST:NOT IMPLEMENTED
trong trường hợp nó được lên kế hoạch cho lần sau.Sự khác biệt này sạch sẽ hơn rất nhiều so với việc trộn lẫn hai thứ khác nhau lên. Nó cũng sẽ làm cho việc gỡ lỗi dễ dàng hơn và xử lý chỉ phức tạp hơn một chút, nếu có.
Vấn đề và thảo luận phát sinh từ thực tế là mã phản hồi HTTP đang được sử dụng để biểu thị trạng thái của dịch vụ có kết quả được cung cấp bởi HTTP hoặc để biểu thị sth. đó không phải là trong phạm vi của máy chủ HTTP. Do sự khác biệt này, câu hỏi không thể được trả lời và tất cả các ý kiến có thể được thảo luận rất nhiều.
Trạng thái của một yêu cầu được xử lý bởi một dịch vụ chứ không phải máy chủ HTTP THỰC SỰ KHÔNG NÊN (RFC 6919) được cung cấp bởi mã phản hồi HTTP. Mã HTTP NÊN (RFC 2119) chỉ chứa thông tin mà máy chủ HTTP có thể cung cấp từ phạm vi của chính nó: cụ thể là, liệu dịch vụ có được tìm thấy để xử lý yêu cầu hay không.
Thay vào đó, một cách khác NÊN được sử dụng để nói với người tiêu dùng về trạng thái của yêu cầu đối với dịch vụ đang thực sự xử lý yêu cầu. Đề xuất của tôi là làm như vậy thông qua một tiêu đề cụ thể. Lý tưởng nhất là cả tên của tiêu đề và nội dung của nó đều tuân theo một tiêu chuẩn giúp người tiêu dùng dễ dàng làm việc với các phản hồi của luận án.
Theo RFC7231 - trang59 ( https://tools.ietf.org/html/rfc7231#page-59 ) định nghĩa của phản hồi mã trạng thái 404 là:
6.5.4. 404 Không tìm thấy Mã trạng thái 404 (Không tìm thấy) cho biết rằng máy chủ gốc không tìm thấy đại diện hiện tại cho tài nguyên đích hoặc không sẵn sàng tiết lộ rằng tồn tại. Mã trạng thái 404 không cho biết việc thiếu đại diện này là tạm thời hay vĩnh viễn; mã trạng thái 410 (Đã qua) được ưu tiên hơn 404 nếu máy chủ gốc biết, có lẽ thông qua một số phương tiện có thể định cấu hình, rằng điều kiện này có thể là vĩnh viễn. Một phản hồi 404 được lưu trữ theo mặc định; tức là, trừ khi được chỉ định bởi định nghĩa phương thức hoặc các điều khiển bộ đệm rõ ràng (xem Mục 4.2.2 của [RFC7234]).
Và điều chính mang đến sự nghi ngờ là định nghĩa về tài nguyên trong bối cảnh trên. Theo cùng RFC (7231) định nghĩa về tài nguyên là:
Tài nguyên: Mục tiêu của yêu cầu HTTP được gọi là "tài nguyên". HTTP không giới hạn bản chất của tài nguyên; nó chỉ định nghĩa một giao diện có thể được sử dụng để tương tác với các tài nguyên. Mỗi tài nguyên được xác định bởi Mã định danh tài nguyên đồng nhất (URI), như được mô tả trong Phần 2.7 của [RFC7230]. Khi khách hàng xây dựng một thông báo yêu cầu HTTP / 1.1, nó sẽ gửi URI đích dưới một trong các dạng khác nhau, như được định nghĩa trong (Phần 5.3 của [RFC7230]). Khi nhận được yêu cầu, máy chủ sẽ xây dựng lại URI yêu cầu hiệu quả cho tài nguyên đích (Mục 5.5 của [RFC7230]). Một mục tiêu thiết kế của HTTP là tách biệt nhận dạng tài nguyên khỏi ngữ nghĩa yêu cầu, điều này có thể thực hiện được bằng cách sử dụng ngữ nghĩa yêu cầu trong phương thức yêu cầu (Phần 4) và một vài trường tiêu đề sửa đổi yêu cầu (Phần 5).
Vì vậy, theo cách hiểu của tôi, mã trạng thái 404 không nên được sử dụng cho yêu cầu GET thành công với kết quả trống. (Ví dụ: danh sách không có kết quả cho bộ lọc cụ thể)
Những điều như vậy có thể là chủ quan và có một số lập luận vững chắc và thú vị ở cả hai bên. Tuy nhiên [theo tôi] trả lại 404 cho dữ liệu bị thiếu là không chính xác . Dưới đây là một mô tả đơn giản để làm rõ điều này:
Không có gì bị phá vỡ, điểm cuối đã được tìm thấy, và bảng và cột được tìm thấy để DB truy vấn và dữ liệu đã được "trả về" thành công!
Bây giờ - cho dù "phản hồi thành công" đó có dữ liệu hay không không quan trọng, bạn đã yêu cầu trả lời dữ liệu "tiềm năng" và phản hồi đó với dữ liệu "tiềm năng" đã được thực hiện. Null, trống vv là dữ liệu hợp lệ.
200 chỉ có nghĩa là bất cứ yêu cầu nào chúng tôi đã làm là thành công. Tôi đang yêu cầu dữ liệu, không có gì sai với HTTP / REST và vì dữ liệu (mặc dù trống) đã được trả về "yêu cầu dữ liệu" của tôi đã thành công.
Trả lại 200 và để người yêu cầu xử lý dữ liệu trống vì mỗi kịch bản cụ thể đảm bảo!
Xem xét ví dụ này:
Dữ liệu này là trống hoàn toàn hợp lệ. Nó có nghĩa là người dùng không có vi phạm. Đây là 200 vì tất cả đều hợp lệ, khi đó tôi có thể làm:
Bạn không có vi phạm, có một bánh muffin việt quất!
Nếu bạn coi đây là 404, bạn đang nói gì? Những vi phạm của người dùng không thể được tìm thấy? Bây giờ, về mặt ngữ pháp là chính xác, nhưng điều đó không đúng trong thế giới REST là thành công hay thất bại là về yêu cầu. Dữ liệu "vi phạm" cho người dùng này có thể được tìm thấy thành công, không có vi phạm nào - một số thực biểu thị trạng thái hợp lệ.
[Ghi chú táo bạo ..]
Trong tiêu đề của bạn, bạn vô tình đồng ý rằng 200 là phản hồi chính xác:
Mã phản hồi REST thích hợp cho một yêu cầu hợp lệ nhưng dữ liệu trống là gì?
Dưới đây là một số điều cần xem xét khi chọn sử dụng mã trạng thái nào, bất kể sự lựa chọn chủ quan và khó khăn:
Mã hóa nội dung phản hồi bằng một enum chung cho phép máy khách bật nó và rẽ nhánh logic tương ứng. Tôi không chắc chắn làm thế nào khách hàng của bạn sẽ phân biệt sự khác biệt giữa 404 "không tìm thấy dữ liệu" và "không tìm thấy tài nguyên web" 404? Bạn không muốn ai đó duyệt đến người dùng Z / 9 và khiến khách hàng thắc mắc như thể yêu cầu hợp lệ nhưng không có dữ liệu nào được trả về.
Tại sao không sử dụng 410? Nó cho thấy tài nguyên được yêu cầu không còn tồn tại và khách hàng sẽ không bao giờ đưa ra yêu cầu cho tài nguyên đó, trong trường hợp của bạn users/9
.
Bạn có thể tìm thêm chi tiết về 410 tại đây: https://www.w3.org/Prot Protocol / rfc2616 / rfc2616-sec10.html
Thật đáng buồn khi một cái gì đó quá đơn giản và được xác định rõ ràng đã trở thành "ý kiến dựa trên" trong chủ đề này.
Máy chủ HTTP chỉ biết "thực thể", là một bản tóm tắt cho bất kỳ nội dung nào, có thể là trang web tĩnh, danh sách kết quả tìm kiếm, danh sách các thực thể khác, mô tả json về nội dung nào đó, tệp phương tiện, v.v.
Mỗi thực thể như vậy dự kiến sẽ được nhận dạng bởi một URL duy nhất, ví dụ:
Nếu một máy chủ tìm thấy tài nguyên theo URL đã cho, thì nội dung của nó là gì - 2G dữ liệu, null, {}, [] - miễn là nó tồn tại, nó sẽ là 200. Nhưng nếu thực thể đó là không biết đến máy chủ, nó được MỞ RỘNG để trả về 404 "Không tìm thấy".
Một sự nhầm lẫn dường như là từ các nhà phát triển nghĩ rằng nếu ứng dụng có trình xử lý cho một hình dạng đường dẫn nhất định, thì đó không phải là một lỗi. Trong mắt của giao thức HTTP, không có vấn đề gì xảy ra trong phần bên trong của máy chủ (ví dụ: bộ định tuyến mặc định đã trả lời hay trình xử lý cho hình dạng đường dẫn cụ thể), miễn là không có thực thể phù hợp trên máy chủ với URL được yêu cầu (yêu cầu tệp MP3, trang web, đối tượng người dùng, v.v.), sẽ trả về nội dung hợp lệ (trống hoặc nếu không), nó phải là 404 (hoặc 410, v.v.).
Một điểm nhầm lẫn khác dường như xoay quanh "không có dữ liệu" và "không có thực thể". Cái trước là về nội dung của một thực thể, và cái sau về sự tồn tại của nó.
Ví dụ 1:
Ví dụ 2:
Ví dụ 3:
404 sẽ rất khó hiểu cho bất kỳ khách hàng nào nếu bạn quay lại chỉ vì không có dữ liệu phản hồi.
Đối với tôi, Mã phản hồi 200 với phần thân trống là đủ để hiểu rằng mọi thứ đều hoàn hảo nhưng không có dữ liệu phù hợp với yêu cầu.
Theo Microsoft: Các loại trả về hành động của Trình điều khiển trong API web ASP.NET Core , cuộn xuống gần hết, bạn sẽ thấy các lỗi sau về 404 liên quan đến một đối tượng không tìm thấy trong cơ sở dữ liệu. Ở đây họ đề xuất rằng 404 phù hợp với Dữ liệu trống.
Như nhiều người đã nêu, 404 là sai lệch và nó không cho phép khách hàng phân biệt đối xử nếu uri yêu cầu không tồn tại hoặc nếu uri được yêu cầu không thể lấy tài nguyên được yêu cầu.
Trạng thái 200 dự kiến sẽ chứa dữ liệu tài nguyên - vì vậy nó không phải là lựa chọn đúng đắn. Trạng thái 204 có nghĩa là một cái gì đó hoàn toàn khác và không nên được sử dụng làm phản hồi cho các yêu cầu GET.
Tất cả các trạng thái hiện có khác không được áp dụng, vì lý do này hay lý do khác.
Tôi đã thấy chủ đề này được thảo luận nhiều lần ở nhiều nơi. Đối với tôi, rõ ràng là để loại bỏ sự nhầm lẫn xung quanh chủ đề, một trạng thái thành công dành riêng là cần thiết. Một cái gì đó như " 209 - Không có tài nguyên để hiển thị".
Đó sẽ là trạng thái 2xx vì không tìm thấy ID nên không được coi là lỗi máy khách (nếu khách hàng biết mọi thứ trong DB của máy chủ, họ sẽ không cần phải hỏi bất cứ điều gì với máy chủ, phải không?). Trạng thái chuyên dụng này sẽ giải quyết tất cả các vấn đề tranh luận với việc sử dụng các trạng thái khác.
Câu hỏi duy nhất là: làm thế nào để RFC chấp nhận điều này như một tiêu chuẩn?