2010-09-01 32 views
10

Tôi đang triển khai dịch vụ web RESTful truy cập cơ sở dữ liệu. Các thực thể trong cơ sở dữ liệu được phiên bản để phát hiện nhiều bản cập nhật. Ví dụ: nếu giá trị hiện tại là {"name":"Bill", "comment":"tinker", "version":3}, nếu một người dùng PUTs {"name":"Bill", "comment":"tailor", "version":3}, yêu cầu sẽ thành công (200 OK) và giá trị mới sẽ là {"name":"Bill", "comment":"tailor", "version":4}. Nếu người dùng thứ hai PUTs {"name":"Bill", "comment":"sailor", "version":3"} yêu cầu đó sẽ không thành công (409 Xung đột) vì số phiên bản không khớp.Trạng thái HTTP 412 (Điều kiện tiên quyết không thành công) và phiên bản cơ sở dữ liệu

Hiện có các giao diện không có sẵn, do đó, không thể thay đổi thiết kế cơ sở dữ liệu. Giao diện RESTful gọi một giao diện hiện có xử lý các chi tiết kiểm tra phiên bản.

Quy tắc chung trong dịch vụ web RESTful là thực hiện theo các chi tiết của HTTP bất cứ khi nào có thể. Sẽ tốt hơn trong trường hợp này để sử dụng tiêu đề có điều kiện trong yêu cầu và trả về 412 Điều kiện tiên quyết Không thành công nếu phiên bản không khớp? Tiêu đề thích hợp dường như là If-Match. Tiêu đề này có một ETag (Thẻ thực thể) có thể là một băm đại diện cho trạng thái hiện tại của tài nguyên.

Nếu tôi đã làm điều này, ETags sẽ vì mục đích xuất hiện, bởi vì phiên bản vẫn sẽ là điều thực sự tôi đang thử nghiệm.

Có lý do nào tôi nên làm điều này, không phải là "làm cho nó yên tĩnh hơn", bất kể điều đó nghĩa là gì?

Trả lời

17

Điều thích hợp cần làm là luôn tuân thủ thông số HTTP nếu bạn đang sử dụng HTTP và lý do chỉ đơn giản là cho phép những người hiểu thông số kỹ thuật hoạt động chính xác.

412 chỉ nên được sử dụng nếu một điều kiện tiên quyết (ví dụ If-Match) gây ra phù hợp với phiên bản thất bại, trong khi 409 nên được sử dụng nếu thực thể sẽ gây ra một cuộc xung đột (spec HTTP bản thân ám chỉ đến hành vi này trong số definition of 409).

Do đó, một khách hàng mà không gửi ETags sẽ không được mong đợi một 412. Ngược lại, một khách hàng mà không gửi ETags sẽ không hiểu rằng đó là ETags đang gây ra một 409.

tôi sẽ dính bằng một cách. Bạn nói rằng "lược đồ cơ sở dữ liệu không thể thay đổi", nhưng điều đó không ngăn bạn (ngay trong lớp máy chủ HTTP) để trích xuất phiên bản từ đại diện datbase và đặt nó trong ETag, và sau đó trên đường vào, lấy tiêu đề If-Match và đưa nó trở lại trong trường phiên bản.

Nhưng thực hiện hoàn toàn trong thân thực thể không bị cấm. Nó chỉ yêu cầu bạn giải thích khái niệm và cách nó hoạt động, trong khi với giải pháp ETag bạn chỉ có thể trỏ mọi người đến thông số HTTP.

Chỉnh sửa: Và cờ phiên bản không phải là băm của tài nguyên hiện tại; một phiên bản khá chấp nhận được. ETag: "3" là một ETag hoàn toàn hợp lệ.

+0

bạn có bất kỳ đầu mối nào về vấn đề của mình không: http://stackoverflow.com/questions/19009312/how-to-detect-412-precondition-failed-errors-in-android-webview-url –

+1

"* Phiên bản cờ không phải là băm của tài nguyên hiện tại * "- nó có tác dụng nếu bạn muốn giảm thiểu nguy cơ người dùng đoán phiên bản mong đợi là gì và bỏ qua kiểm tra đồng thời. – James

+1

Heh :-) Tôi không thực sự nói rằng {{ETag: "3"}} là một ý tưởng tốt ... Làm cho nó mờ đục nói chung là một ý tưởng tốt, mặc dù nó làm giảm khả năng hiển thị. Xem xét {{ETag: "3: eccbc8"}} - trong đó "eccbc8 là 6 ký tự đầu tiên của md5sum của ký tự" 3 ".Điều này buộc khách hàng sử dụng thẻ thực thể theo cách họ dự định; nhưng giữ khả năng hiển thị ("3" là ở đó để con người có thể giải thích điều này như là "phiên bản 3"). Chúng tôi vẫn không băm nội dung thực sự. – mogsie

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