Phản hồi REST thích hợp cho bảng trống?


106

Giả sử bạn muốn nhận danh sách người dùng bằng cách gọi GETđến api/users, nhưng hiện tại bảng đã bị cắt bớt nên không có người dùng. Phản ứng thích hợp cho tình huống này là gì: 404hoặc 204?


19
Tôi muốn đáp ứng với 200 và một bộ sưu tập rỗng (không phải là một cơ thể phản hồi trống mà đúng hơn là một bộ sưu tập không có yếu tố bên trong, điều này sẽ trông khác tùy thuộc vào định dạng trả lại)
toniedzwiedz

4
404 trong ngữ cảnh này có lẽ sẽ phù hợp hơn cho 'table not found'. Tôi muốn trả lại một danh sách trống.
mata


2
@EJoshuaS Không phải vậy. Cả hai câu hỏi đều là của tôi và rất cũ. Chúng giống nhau nhưng không trùng lặp.
IMB

1
@EJoshuaS Chúng rõ ràng không phải là bản sao. Câu hỏi này là về /api/userstrong khi câu đó là về /api/users/1.
Franklin Yu

Câu trả lời:


231

Tôi cũng không muốn nói.

Tại sao không phải là 404 (Không tìm thấy)?

Mã trạng thái 404 nên được dành riêng cho các trường hợp không tìm thấy tài nguyên. Trong trường hợp này, tài nguyên của bạn là một tập hợp người dùng . Bộ sưu tập này tồn tại nhưng nó hiện đang trống. Cá nhân tôi, tôi sẽ rất bối rối với tư cách là tác giả của một ứng dụng khách cho ứng dụng của bạn nếu tôi nhận được một 200ngày và một 404ngày hôm sau chỉ vì ai đó tình cờ xóa một vài người dùng. Tôi phải làm gì bây giờ? URL của tôi có sai không? Có ai đó đã thay đổi API và bỏ qua việc chuyển hướng không.

Tại sao không 204 (Không có Nội dung)?

Đây là một đoạn trích từ mô tả của mã trạng thái 204 của w3c

Máy chủ đã hoàn thành yêu cầu nhưng không cần trả lại phần thân thực thể và có thể muốn trả về thông tin cập nhật.

Mặc dù điều này có vẻ hợp lý trong trường hợp này, nhưng tôi nghĩ nó cũng sẽ khiến khách hàng bối rối. A 204được cho là chỉ ra rằng một số hoạt động đã được thực hiện thành công và không cần trả lại dữ liệu nào. Đây là một phản hồi hoàn hảo cho một DELETEyêu cầu hoặc có thể kích hoạt một số tập lệnh không cần trả lại dữ liệu. Trong trường hợp này api/users, bạn thường mong đợi nhận được bản trình bày về tập hợp người dùng của mình. Việc gửi nội dung phản hồi một lần và không gửi lần khác là không nhất quán và có khả năng gây hiểu lầm.

Tại sao tôi sử dụng 200 (OK)

Vì những lý do đã đề cập ở trên (tính nhất quán), tôi sẽ trả về một đại diện của một tập hợp rỗng. Giả sử bạn đang sử dụng XML. Nội dung phản hồi bình thường cho một tập hợp người dùng không trống có thể trông giống như sau:

<users>
  <user>
    <id>1</id>
    <name>Tom</name>
  </user>
  <user>
    <id>2</id>
    <name>IMB</name>
  </user>
</users>

và nếu danh sách trống, bạn chỉ có thể trả lời như sau (trong khi vẫn sử dụng a 200):

<users/>

Dù bằng cách nào, khách hàng sẽ nhận được nội dung phản hồi tuân theo một định dạng nhất định, nổi tiếng. Không có sự nhầm lẫn không cần thiết và kiểm tra mã trạng thái. Ngoài ra, không có định nghĩa mã trạng thái nào bị vi phạm. Mọi người đều vui vẻ.

Bạn có thể làm tương tự với JSON hoặc HTML hoặc bất kỳ định dạng nào bạn đang sử dụng.


4
Hoàn toàn đồng ý. Và đối với REST, tôi sẽ chỉ cần gửi lại một mã trạng thái của 200 với một mảng trống: [].
Chad Johnson

Có ý nghĩa. Không cần phải làm cho nó khó hơn. 404 sẽ khó hiểu.
Witold Kaczurba

Hãy giả sử API mô tả các đồng tiền trong túi của bạn, với các điểm cuối: GET /singleCoin- trả lại một đồng xu ngẫu nhiên từ túi của bạn, GET /severalCoins- trả lại một số đồng từ túi mà bạn có thể lấy trong một lần. Giả sử bạn không có xu nào trong túi hiện tại. Khi bạn yêu cầu GET /singleCoinbạn sẽ nhận được 404 Not Found, nhưng khi bạn yêu cầu, GET /severalCoinsbạn sẽ nhận được 200 OKvới danh sách trống []. Một sự thật - bạn không có đồng xu nào, được mô tả với những phản hồi khác nhau, tại sao? Tôi nên nói rằng tốt hơn hết là nên lấy 404 Not Found, bởi vì không có đồng xu nào được tìm thấy trong túi của bạn.
sempasha 17/07/19

1
@sempasha Nó phụ thuộc vào những gì bạn muốn nói GET /severalCoins. Nếu bạn bắt buộc GET /severalCoins phải trả lại một số đồng xu thì nó không nên là 200 vì nó không ổn; máy chủ không thể cung cấp những gì khách hàng muốn. Đối với /singleCoinđiều này là hiển nhiên bởi vì khách hàng muốn chính xác một đồng xu, không hơn không kém. Điều này là tương tự cho /coins/7. Ngược lại đối với /coinsđiểm cuối, khách hàng thường không mong đợi một đồng tiền, một đồng hoặc nhiều đồng. Tất cả chúng đều là phản hồi hợp lệ. Nếu không có đồng xu, thì đây là những gì họ muốn. Nó giống như một emply List<Coin>trong Java, thay vì null.
Franklin Yu

15

Tôi sẽ trả lời một trong hai mã tùy thuộc vào tình huống thời gian chạy:

404 không tìm thấy)

Câu trả lời này là khá chính xác nếu bạn không có bảng. Không chỉ là bảng trống mà KHÔNG CÓ BẢNG NGƯỜI DÙNG. Nó xác nhận ý tưởng chính xác - không có tài nguyên. Các tùy chọn khác là cung cấp thêm thông tin chi tiết TẠI SAO bảng của bạn không có, có một vài mã chi tiết hơn nhưng 404 khá tốt để đề cập đến trường hợp bạn thực sự không có bảng.

200 (Được)

Tất cả các trường hợp bạn có bảng nhưng nó trống hoặc bộ xử lý yêu cầu của bạn đã lọc ra tất cả các kết quả. Điều này có nghĩa là 'yêu cầu của bạn là đúng, mọi thứ đều ổn nhưng bạn không khớp với bất kỳ dữ liệu nào chỉ vì chúng tôi không có dữ liệu hoặc chúng tôi không có dữ liệu nào phù hợp với yêu cầu của bạn. Điều này sẽ khác với câu trả lời từ chối bảo mật. Tôi cũng bỏ phiếu trả lại 200 trong trường hợp bạn có một số dữ liệu và nói chung bạn được phép truy cập vào bảng nhưng không có quyền truy cập vào tất cả dữ liệu phù hợp với yêu cầu của bạn (dữ liệu đã được lọc ra vì bảo mật cấp đối tượng nhưng nói chung bạn được phép yêu cầu).


10

Nếu bạn đang mong đợi danh sách đối tượng người dùng, giải pháp tốt nhất là trả về một danh sách trống ([]) với 200 OK hơn là sử dụng phản hồi 404 hoặc 204.


2

chắc chắn trả về 200.

404 có nghĩa là không tìm thấy tài nguyên. Nhưng tài nguyên tồn tại. Ngoài ra, nếu phản hồi có trạng thái 404. Làm thế nào bạn có thể biết danh sách người dùng trống hoặc đầy?


  • '/ users' nếu trống sẽ trả về '200'.
  • '/ users / 1' nếu không tìm thấy id. nên trả về 404.

2

Nó phải 200 OK với danh sách trống.

Lý do: Bảng trống có nghĩa là bảng tồn tại nhưng không có bất kỳ bản ghi nào.

404 Không tìm thấy có nghĩa là điểm kết thúc được yêu cầu không tồn tại.

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.