2013-08-10 30 views
5

Dịch vụ RESTful của tôi bao gồm tài nguyên đại diện cho một mục ACL. Để cập nhật ACL này, một khách hàng thực hiện yêu cầu PUT với ACL mới làm thực thể của nó. Khi thành công, thực thể phản hồi PUT có chứa phiên bản chính thức đã được vệ sinh của ACL mới.Mã trạng thái HTTP REST cho "thành công và do đó bạn không còn quyền truy cập"

Trong hầu hết các trường hợp, mã trạng thái phản hồi HTTP khá rõ ràng. 200 khi thành công, 403 nếu người dùng không được phép chỉnh sửa ACL, 400 nếu ACL mới không đúng định dạng, 404 nếu họ cố đặt ACL trên một mục không tồn tại, 412 nếu tiêu đề If-Match không khớp và như.

Có một trường hợp, tuy nhiên, nơi mã trạng thái HTTP chính xác không rõ ràng. Nếu người dùng được xác thực sử dụng PUT để tự xóa mình khỏi ACL thì sao? Chúng tôi cần phải chỉ ra rằng yêu cầu đã thành công nhưng họ không còn có quyền truy cập vào tài nguyên nữa.

Tôi đã xem xét trả lại 200 với ACL mới trong thực thể PUT, nhưng điều này thiếu bất kỳ dấu hiệu nào cho thấy rằng chúng không còn khả năng GET tài nguyên nữa. Tôi đã xem xét trả lại trực tiếp 403, nhưng điều này không cho biết rằng PUT đã thành công. Tôi đã xem xét việc trả lại 303 với số Location trỏ trở lại cùng một tài nguyên (trong đó GET tiếp theo sẽ cung cấp số 403), nhưng điều này có vẻ như lạm dụng 303 do tài nguyên chưa di chuyển.

Vậy mã trạng thái REST HTTP đúng cho "thành công" là gì và do đó bạn không còn quyền truy cập "?

+0

Có bất kỳ câu trả lời nào trong số này hữu ích không? – Kylar

+0

@Kylar: Có, một vài. Khó chọn đúng người để chấp nhận. – dkarp

Trả lời

3

200 là câu trả lời thích hợp, vì nó cho biết thành công (như bất kỳ mã 2xx nào ngụ ý). Bạn có thể phân biệt sự thiếu quyền của người dùng trong phản hồi (hoặc, nếu bạn không muốn, 204 là tốt). Mã trạng thái không có hợp đồng mà các yêu cầu trong tương lai sẽ trả lại cùng một mã: phản hồi 200 cho PUT không có nghĩa là GET tiếp theo không thể trả về 403. Nói chung, các máy chủ không bao giờ nên nói với khách hàng điều gì sẽ xảy ra nếu họ phát hành một yêu cầu. Các máy khách HTTP hầu như luôn luôn nhảy trước khi chúng nhìn và được chuẩn bị để xử lý hầu như mọi mã phản hồi.

Bạn nên đọc số updated description of the PUT method in httpbis; nó thảo luận không chỉ việc sử dụng 200/204 mà chỉ ra một cách đọc cẩn thận mà trả về một biểu diễn biến đổi trong phản ứng tức thời với PUT là không thích hợp; thay vào đó, hãy sử dụng tiêu đề ETag hoặc Last-Modified để cho biết thực thể khách hàng đã gửi có được chuyển đổi hay không. Nếu có, client sẽ phát hành GET tiếp theo thay vì mong đợi biểu diễn mới được gửi để phản hồi PUT, nếu không có lý do nào khác để cập nhật bất kỳ cache nào trên đường đi (vì phản hồi với PUT không thể lưu vào bộ đệm) . Section 6.3.1 đồng ý: phản hồi đối với PUT phải thể hiện trạng thái của hành động chứ không phải chính tài nguyên. Cũng lưu ý rằng, đối với ACL mới, bạn PHẢI trả lại 201, không phải 200.

+0

"Máy chủ gốc KHÔNG gửi trường tiêu đề validator (Phần 7.2), chẳng hạn như trường ETag hoặc Lần sửa đổi lần cuối, trong phản hồi thành công cho PUT trừ khi dữ liệu biểu diễn của yêu cầu được lưu mà không có bất kỳ chuyển đổi nào áp dụng cho nội dung (ví dụ: dữ liệu biểu diễn mới của tài nguyên giống hệt với dữ liệu biểu diễn nhận được trong yêu cầu PUT) và giá trị trường validator phản ánh biểu diễn mới. " Nói cách khác, trả về một 'ETag' chỉ khi thực thể' PUT' khớp chính xác với thực thể sẽ được trả về từ 'GET' tiếp theo? – dkarp

+0

@dkarp đúng. – fumanchu

+0

Tôi đã không tìm thấy đề xuất nào cũng không cấm trả lại biểu diễn của tài nguyên trong phản hồi yêu cầu PUT. Nếu không, câu trả lời là tốt. –

0

Câu hỏi rất thú vị :-) Đây là lý do tại sao tôi yêu REST, đôi khi có thể khiến bạn phát điên. Đọc w3 http status code definitions tôi sẽ chọn (điều này tất nhiên chỉ là thiển ý của tôi) là một trong những:

  • 202 Được chấp nhận - vì đây có nghĩa là "cũng vâng tôi đã yêu cầu của bạn, tôi sẽ xử lý nó, nhưng quay lại sau và xem những gì xảy ra "- và khi người dùng quay lại sau, cô ấy sẽ nhận được 403 (hành vi được mong đợi)
  • 205 Đặt lại nội dung -" Vâng, tôi hiểu rằng bạn muốn xóa chính mình, hãy thực hiện yêu cầu mới, khi bạn quay lại bạn sẽ nhận được 403 "

Mặt khác (chỉ xuất hiện trong tâm trí của tôi), tại sao bạn nên giới thiệu một logic riêng biệt và phân biệt trường hợp và không sử dụng 200? Phần còn lại này có được sử dụng từ một số ứng dụng khách có giao diện người dùng không? Và người dùng phần còn lại sẽ hiển thị cửa sổ bật lên cho người dùng cuối "Bạn có chắc chắn muốn xóa chính mình khỏi ACL không?" ở đây trường hợp có thể được xử lý nếu phần còn lại của bạn trả lại 200 và chỉ hiển thị cửa sổ bật lên "Bạn có chắc chắn muốn xóa người dùng có tên khỏi ACL không?", không cần phân biệt hai trường hợp. Nếu phần còn lại này sẽ được sử dụng cho một số giao tiếp dịch vụ tới dịch vụ (tức là chỉ được gọi từ chương trình khác) một lần nữa tại sao bạn nên phân biệt các trường hợp ở đây chương trình sẽ không quan tâm người dùng nào sẽ bị xóa khỏi ACL.

Hy vọng điều đó sẽ hữu ích.

+0

Cả hai thứ này đều sai. 202 là để tiếp tục xử lý. 205 là yêu cầu giao diện người dùng xóa biểu mẫu. – fumanchu

+0

Vâng, bạn đã đúng, có lẽ tôi diễn giải chúng sai. Tuy nhiên, tôi tiếp tục thấy không có điểm trong việc giới thiệu logic riêng biệt và phân biệt tình huống này từ trường hợp bình thường khi người dùng xóa một người dùng khác. Điều này có thể được xử lý trên cấp độ UI nếu nó rất quan trọng với thông báo cảnh báo thích hợp. –

1

Bạn có thể muốn xem mã phản hồi HTTP "204 No Content" (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html), cho biết rằng "máy chủ đã đáp ứng yêu cầu [được xóa khỏi ACL] nhưng không cần phải trả lại một thực thể- cơ thể, và có thể muốn trả về thông tin đã được cập nhật "(ở đây, là kết quả của việc loại bỏ thành công). Mặc dù bạn không được phép trả lại nội dung thư với 204, nhưng bạn có thể trả lại tiêu đề thực thể cho biết các thay đổi đối với quyền truy cập của người dùng vào tài nguyên.Tôi có ý tưởng từ Amazon S3 - họ trả về 204 khi yêu cầu DELETE thành công (http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html), có vẻ giống với tình huống của bạn vì bạn tự xóa mình khỏi ACL, bạn đã chặn quyền truy cập vào tài nguyên đó trong tương lai.

2

Bạn đang nhầm lẫn hai ý tưởng ngữ nghĩa và cố gắng kết hợp chúng thành một mã phản hồi duy nhất.

Đầu tiên: Bạn đã tạo thành công ACL tại vị trí mà bạn đang cố gắng. Phản hồi ngữ nghĩa chính xác (trong kịch bản RESTful hoặc không phải là RESTful) là 201 Đã tạo. Từ RFC: "Yêu cầu đã được đáp ứng và tạo ra một nguồn tài nguyên mới được tạo."

Thứ hai: Người dùng đã thực thi PUT không còn quyền truy cập vào tài nguyên này nữa. Đây là một ý tưởng thoáng qua - điều gì xảy ra nếu ACL được cập nhật, hoặc một cái gì đó thay đổi trước yêu cầu tiếp theo? Ý tưởng cho rằng người dùng không có quyền truy cập vào tài nguyên thuộc bất kỳ loại nào (và điều này bao gồm tài nguyên ACL) chỉ là vấn đề đối với phạm vi của yêu cầu đó. Trước khi yêu cầu tiếp theo được thực thi, có thể thay đổi. Trên một yêu cầu duy nhất mà người dùng không có quyền truy cập vào nội dung nào đó, bạn phải trả lại 403 Forbidden.

Phương pháp PUT của bạn phải trả về giá 201. Nếu khách hàng lo lắng về việc liệu nó có truy cập được nữa hay không, nó sẽ đưa ra yêu cầu tiếp theo để xác định trạng thái của nó.

+0

Không đồng ý về 201. Giả sử mỗi mục có ACL mặc định, sau đó PUT trả về đúng 200. – grzes

Các vấn đề liên quan