2015-05-25 13 views
8

Tôi có một thực thể với một số thuộc tính, nói «project». Ngoài các thuộc tính đơn giản, dự án có thể có một danh sách «trạng thái» mà cái cuối cùng là thuộc tính hiện tại. Tôi có một biểu mẫu web để tạo/chỉnh sửa dự án. Tất cả các thuộc tính của dự án này có thể được thay đổi trong biểu mẫu này và người dùng cũng có thể thêm trạng thái mới cho dự án (nhưng họ không thể thay đổi hoặc xóa trạng thái cũ).Cập nhật các đối tượng kết hợp trong tài nguyên RESTful

Trạng thái dự án hoàn toàn là các đối tượng hỗn hợp, không có bất kỳ ý nghĩa hay nhận dạng đặc biệt nào ngoài phạm vi dự án và chúng không được giải quyết trực tiếp, vì vậy chúng rõ ràng không xứng đáng với tài nguyên REST đặc biệt gốc.

Theo kiến ​​trúc REST, tôi đã tạo tài nguyên được gọi là/projects. POST được sử dụng để tạo một dự án mới, và PUT được sử dụng để thay đổi một dự án hiện có.

Tuy nhiên, tôi không muốn khách hàng PUT dự án cùng với tất cả trạng thái lịch sử, trước hết vì bộ sưu tập này quá nặng và thứ hai vì logic nghiệp vụ chỉ cho phép thêm trạng thái chứ không thay đổi hoặc xóa chúng nên PUTting dự án cùng với tất cả các trạng thái của nó không có bất kỳ ý nghĩa nào.

Ngắt một dự án chỉ với một trạng thái mới cũng không phải là một tùy chọn, vì nó vi phạm tính ngẫu nhiên của PUT.

Tôi cũng không thích ý tưởng BẬT trạng thái trong yêu cầu HTTP thứ hai, nói/project/{id}/status, vì điều đó sẽ phá vỡ tính nguyên tử của hoạt động cập nhật từ quan điểm của người dùng. Nếu yêu cầu thứ hai này bị mất trên dây, thì dự án sẽ xuất hiện không phù hợp với người dùng đã chỉnh sửa nó (các thuộc tính đã thay đổi, nhưng trạng thái vẫn giữ nguyên). Tạo các giao dịch RESTful "" có vẻ như quá mức cần thiết (và cũng dễ bị lỗi) cho nhiệm vụ đơn giản này là cập nhật một thực thể dường như nguyên khối.

Loại sự cố này khá phổ biến trong công việc của tôi và có thể được khái quát hóa như vậy: cách chính xác và nguyên tử của cách cập nhật một thực thể phức hợp phức tạp mà chỉ cho phép cập nhật một phần bởi logic nghiệp vụ?

Trả lời

3

Tôi nghĩ rằng nếu bạn muốn làm cập nhật từng phần (nó thực sự là trường hợp của bạn), bạn nên sử dụng phương pháp PATCH. Điều này cho phép cập nhật dự án mà không có phụ thuộc (trạng thái) hoặc phụ thuộc mà không có gợi ý dự án.

Bạn có thể nhận thấy rằng có một định dạng để mô tả các hoạt động cần thực hiện trong phương thức PATCH. Nó được gọi là Bản vá JSON (xem https://tools.ietf.org/html/rfc6902). Định dạng này mô tả những gì bạn muốn làm trong yêu cầu của bạn: thêm một phần tử, cập nhật nó, loại bỏ nó, ...

Tôi nghĩ rằng bạn có thể có một cái gì đó như thế nếu bạn muốn (ví dụ) để cập nhật tên một dự án cụ thể, loại bỏ một trạng thái (nó cũng là một mẫu kể từ khi tôi đọc mà bạn muốn cấm này!) và thêm một cái mới trong một yêu cầu nguyên tử:

PATCH /projects/1 
[ 
    { 
     "op": "replace", 
     "path": "/name", 
     "value": "the new name of the project" 
    }, 
    { 
     "op": "remove", 
     "path": "/statuses/1" 
    }, 
    { 
     "op": "add", 
     "path": "/statuses/", 
     "value": { 
      "name": "my status", 
      (...) 
     } 
    } 
] 

Chú ý rằng bạn có thể đặt những gì bạn muốn trong thuộc tính name để xác định phần tử liên quan trong trạng thái tài nguyên. Vì vậy, /statuses/1 có thể là phần tử thứ hai trong mảng, trạng thái có id có giá trị 1 hoặc một thứ khác.

Xử lý phía máy chủ cho yêu cầu có thể là nguyên tử.

Tôi đã viết một bài đăng trên blog về cập nhật hàng loạt: https://templth.wordpress.com/2015/05/14/implementing-bulk-updates-within-restful-services/. Tôi nghĩ rằng phần "Triển khai cập nhật hàng loạt" có thể tương ứng với những gì bạn tìm kiếm.

Hy vọng nó sẽ giúp bạn, Thierry

+0

Wow. Tôi không biết về RFC này. Cảm ơn! –

+0

Bạn được chào đón! Rất vui khi biết rằng điều này giúp bạn! –

5

Bạn có cần HTTP PATCH không? Nó là động từ thể hiện cập nhật delta cho một tài nguyên.

http://tools.ietf.org/html/rfc5789

+0

Theo RFC, điều này có vẻ là những gì tôi muốn. Nhưng tôi đã luôn luôn nghĩ về phương pháp PATCH như một chút của một hack, và không chắc chắn về cách nó phù hợp với kiến ​​trúc REST. Hầu hết các mô tả của REST không đề cập đến phương pháp PATCH. Tôi hiểu rằng REST chỉ đơn giản là một mô hình kiến ​​trúc, không phải là một tiêu chuẩn, nhưng vẫn còn, là có bất kỳ nguồn "kinh điển" thông tin về cách PATCH phù hợp trong kiến ​​trúc tổng thể REST? –

+1

REST ủng hộ để sử dụng các động từ HTTP (GET, POST, ...) trên các tài nguyên/thực thể tùy thuộc vào ngữ cảnh. Sử dụng HTTP PATCH để cập nhật một phần trên một tài nguyên/thực thể là RESTful vì nó có thể. Đúng là PATCH dường như bị lãng quên/bỏ qua, nhưng không có gì hơn thế. Nó có rất nhiều lý do, nhưng không ai trong số đó là vì việc sử dụng nó có thể xung đột với một thiết kế RESTful. – Jepe

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