REST DELETE có thực sự bình thường không?


165

XÓA được coi là bình thường.

Nếu tôi XÓA http://example.com/account/123 thì nó sẽ xóa tài khoản.

Nếu tôi làm lại, tôi có mong đợi 404 không, vì tài khoản không còn tồn tại? Điều gì xảy ra nếu tôi cố gắng XÓA một tài khoản chưa từng tồn tại?


11
Ngoài các câu trả lời, tôi đề nghị không nên tập trung quá nhiều vào đặc điểm bình thường nói chung: nó không nói gì về giao hoán và các yêu cầu đồng thời. Ví dụ: N + 1 của cùng một yêu cầu PUT "R1" sẽ có cùng tác dụng, nhưng bạn không biết liệu một khách hàng khác có thực hiện một yêu cầu PUT / DELETE "R2" khác ở giữa bạn hay không, vì vậy trong khi n R1 = R1 và m R2 = R2, một cái gì đó mà bạn nhận được các yêu cầu "R1" và "R2" xen kẽ sẽ không nhất thiết phải "trông" bình thường nếu bạn chỉ xem viễn cảnh của một khách hàng.
Bruno

Câu trả lời:


187

Idempotence đề cập đến trạng thái của hệ thống sau khi yêu cầu đã hoàn thành


Trong mọi trường hợp (ngoài các vấn đề lỗi - xem bên dưới), tài khoản không còn tồn tại.

Từ đây

"Các phương thức cũng có thể có thuộc tính" idempotence "trong đó ( ngoài các vấn đề lỗi hoặc hết hạn ), các tác dụng phụ của N> 0 yêu cầu giống hệt như đối với một yêu cầu. Các phương thức GET, HEAD, PUT và DELETE chia sẻ thuộc tính này. Ngoài ra, các phương thức TÙY CHỌN và TRACE KHÔNG NÊN có tác dụng phụ, và do đó vốn dĩ không có tác dụng. "


Bit khóa có tác dụng phụ của N> 0 yêu cầu giống hệt như đối với một yêu cầu.

Bạn sẽ đúng khi hy vọng rằng mã trạng thái sẽ khác nhưng điều này không ảnh hưởng đến khái niệm cốt lõi về tính không ổn định - bạn có thể gửi yêu cầu nhiều lần mà không cần thay đổi thêm về trạng thái của máy chủ.


3
Tác dụng phụ! == Trạng thái máy chủ
wprl

2
@wprl Có một cuộc tranh luận về "tác dụng phụ" này thực sự là gì. Nó có thể là "trạng thái máy chủ" hoặc nó có thể là phản hồi được gửi đến máy khách. leedavis81.github.io/is-a-http-delete-requests-idempotent
Alireza

Đây là một đối số 404 trên XÓA thứ hai thực sự có thể thay đổi trạng thái của máy chủ: stackoverflow.com/a/45194747/317522
Paulo Merson

1
@PauloMerson Cảm ơn, cá nhân tôi không nghĩ vấn đề là lần trở lại thứ hai là 404 hay 200, trạng thái của máy chủ không thay đổi nên tôi rất vui vì điều đó.
Chris McCauley

46

Idempotent là về tác dụng của yêu cầu, không phải về mã phản hồi mà bạn nhận được.

http://www.w3.org/Prot Protocol / rfc2616 / rfc2616-sec9.html # secec.1.1.2 nói:

Các phương thức cũng có thể có thuộc tính "idempotence" trong đó (ngoài các vấn đề lỗi hoặc hết hạn), các tác dụng phụ của N> 0 yêu cầu giống hệt như đối với một yêu cầu.

Mặc dù bạn có thể nhận được một mã phản hồi khác nhau, nhưng hiệu quả của việc gửi các yêu cầu XÓA N + 1 đến cùng một tài nguyên có thể được coi là giống nhau.


13

Sự khác biệt quan trọng là idempotent đề cập đến tác dụng phụ , không phải tất cả các tác dụng hoặc phản ứng. Nếu bạn làm như vậy DELETE http://example.com/account/123thì hiệu quả là tài khoản 123 hiện đã bị xóa khỏi máy chủ. Đó là hiệu ứng một và duy nhất, một và chỉ thay đổi trạng thái của máy chủ. Bây giờ hãy nói rằng bạn thực hiện lại cùng một DELETE http://example.com/account/123yêu cầu, máy chủ sẽ phản hồi khác nhau, nhưng trạng thái của nó là như nhau.

Nó không giống như yêu cầu XÓA đã quyết định thay đổi trạng thái máy chủ theo một cách khác vì tài khoản bị thiếu, chẳng hạn như xóa tài khoản khác hoặc để lại nhật ký lỗi. Không, bạn có thể gọi cùng một yêu cầu XÓA một triệu lần và bạn có thể chắc chắn rằng máy chủ ở trạng thái giống như lần đầu tiên bạn gọi nó .


7

Từ RFC HTTP :

Các phương thức cũng có thể có thuộc tính "idempotence" trong đó (ngoài các vấn đề lỗi hoặc hết hạn), các tác dụng phụ của N> 0 yêu cầu giống hệt như đối với một yêu cầu.

Lưu ý đó là "tác dụng phụ", không phải "phản ứng".


7

Đúng. Bất kể mã phản hồi.

Từ RFC mới nhất cho HTTP 1.1 (nhấn mạnh của tôi):

Các phương thức tạm thời được phân biệt vì yêu cầu có thể được lặp lại tự động nếu xảy ra lỗi giao tiếp trước khi máy khách có thể đọc phản hồi của máy chủ. Ví dụ: nếu khách hàng gửi yêu cầu PUT và kết nối cơ bản bị đóng trước khi nhận được bất kỳ phản hồi nào, thì khách hàng có thể thiết lập kết nối mới và thử lại yêu cầu tạm thời. Nó biết rằng việc lặp lại yêu cầu sẽ có tác dụng như mong muốn, ngay cả khi yêu cầu ban đầu thành công, mặc dù phản hồi có thể khác nhau.

Nó nói rõ ràng rằng phản ứng có thể khác nhau. Quan trọng hơn, nó chỉ ra lý do của khái niệm: nếu một hành động là bình thường, khách hàng có thể lặp lại hành động khi gặp bất kỳ lỗi nào và biết rằng nó sẽ không sụp đổ bất cứ điều gì khi làm như vậy; nếu không, máy khách sẽ phải thực hiện một truy vấn bổ sung (có thể GET) để xem liệu truy vấn trước có hiệu quả hay không, trước khi nó lặp lại hành động một cách an toàn. Miễn là máy chủ có thể đảm bảo như vậy, thì hành động đó là bình thường. Trích dẫn từ một bình luận khác :

Tính toán idempotence là về sự mạnh mẽ của một hệ thống. Vì mọi thứ có thể thất bại (ví dụ như mất mạng), khi phát hiện lỗi, bạn sẽ phục hồi như thế nào? Phục hồi đơn giản nhất là chỉ cần làm lại, nhưng điều đó chỉ hoạt động nếu thực hiện lại là không cần thiết. Ví dụ discard(x)là idempotent, nhưng pop()không. Đó là tất cả về phục hồi lỗi.


2

Tôi nghĩ điều tương tự, 404 - Tài khoản không tồn tại.

Bạn có thể tranh luận 400 - Yêu cầu xấu. Nhưng theo nghĩa REST, đối tượng bạn yêu cầu thực hiện một hành động không tồn tại. Điều đó chuyển thành 404.


1
Để tạo 400, bạn sẽ phải biết rằng đối tượng đã từng tồn tại, rất không yên tâm.
annakata

1
@annakata, 400 thậm chí không dành cho các tài nguyên đã từng tồn tại (có lẽ bạn có 410 / Đã qua đời), đó là cho các 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."
Bruno

3
@Bruno - Tôi biết ý nghĩa của nó, OP đã trích dẫn nó.
annakata

1
Tôi nghĩ 200 sẽ ổn thôi. Bạn muốn trạng thái của máy chủ là tài khoản đã biến mất. Có vấn đề gì yêu cầu thực sự làm cho nó đi? Nó vẫn tiếp tục yêu cầu thứ hai, trạng thái máy chủ không thay đổi.
Andy

1

Trích dẫn từ câu trả lời khác của tôi ở đây :

Trong lịch sử, RFC 2616, được xuất bản năm 1999, là thông số kỹ thuật HTTP 1.1 được tham khảo nhiều nhất. Thật không may, mô tả của nó về tính không ổn định là mơ hồ , để lại chỗ cho tất cả những cuộc tranh luận này. Nhưng thông số kỹ thuật đó đã được thay thế bởi RFC 7231. Được trích dẫn từ RFC 7231, phần 4.2.2 Phương pháp Idempotent , nhấn mạnh của tôi:

Một phương thức yêu cầu được coi là "idempotent" nếu HIỆU QUẢ dự định TRÊN MÁY CHỦ của nhiều yêu cầu giống hệt nhau với phương thức đó giống như hiệu ứng cho một yêu cầu như vậy. Trong số các phương thức yêu cầu được xác định bởi thông số kỹ thuật này, PUT, DELETE và các phương thức yêu cầu an toàn là tạm thời .

Vì vậy, nó được viết trong thông số kỹ thuật, tính không thay đổi là tất cả về hiệu ứng trên máy chủ. XÓA đầu tiên trả về 204 và sau đó XÓA sau đó trả về 404, mã trạng thái khác nhau như vậy KHÔNG làm cho XÓA không phải là idempotent. Sử dụng đối số này để biện minh cho lợi nhuận 204 tiếp theo, đơn giản là không liên quan.


OK vì vậy nó không phải là về idempotency. Nhưng sau đó, một câu hỏi tiếp theo có thể là, nếu chúng ta vẫn chọn sử dụng 204 trong lần XÓA tiếp theo thì sao? Là nó ổn?

Câu hỏi hay. Động lực là dễ hiểu: cho phép khách hàng vẫn đạt được kết quả như mong muốn, mà không phải lo lắng về việc xử lý lỗi. Tôi có thể nói, trả lại 204 trong lần XÓA tiếp theo, là một "lời nói dối trắng" phía máy chủ phần lớn vô hại, mà phía khách hàng sẽ không ngay lập tức nhận ra sự khác biệt. Đó là lý do tại sao có những người làm điều đó trong tự nhiên và nó vẫn hoạt động. Chỉ cần lưu ý rằng, lời nói dối đó có thể được coi là kỳ lạ về mặt ngữ nghĩa, bởi vì "NHẬN / không tồn tại" trả về 404 nhưng "XÓA / không tồn tại" mang lại 204, tại thời điểm đó, khách hàng sẽ nhận ra dịch vụ của bạn không tuân thủ đầy đủ phần 6.5.4 404 Không tìm thấy .

Nhưng sau đó, cách dự định được gợi ý bởi RFC 7231, tức là trả lại 404 cho lần XÓA tiếp theo, không nên là vấn đề ngay từ đầu. Nhiều nhà phát triển đã chọn để làm điều đó. Điều đó có lẽ là bởi vì, bất kỳ ứng dụng khách nào thực hiện HTTP DELETE (hoặc bất kỳ phương thức HTTP nào, đối với vấn đề đó), sẽ không mù quáng cho rằng kết quả sẽ luôn thành công 2xx. Và sau đó, khi nhà phát triển bắt đầu xem xét xử lý lỗi, 404 Not Found sẽ là một trong những lỗi đầu tiên xuất hiện trong đầu. Vào thời điểm đó, anh ấy / cô ấy hy vọng sẽ đưa ra một kết luận rằng, nó an toàn về mặt ngữ nghĩa cho một hoạt động XÓA HTTP để bỏ qua lỗi 404. Vấn đề được giải quyết.

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.