2008-11-20 27 views
69

Tôi muốn một số lời khuyên về thiết kế API REST cho phép khách hàng thêm/xóa số lượng lớn đối tượng vào bộ sưu tập một cách hiệu quả.Thao tác sưu tập số lượng lớn thông qua API REST (RESTful)

Thông qua API, khách hàng cần có thể thêm các mục vào bộ sưu tập và xóa các mục khỏi bộ sưu tập cũng như thao tác với các mục hiện có. Trong nhiều trường hợp, khách hàng sẽ muốn thực hiện cập nhật hàng loạt cho bộ sưu tập, ví dụ: thêm 1000 mục và xóa 500 mục khác nhau. Có vẻ như khách hàng sẽ có thể thực hiện điều này trong một giao dịch duy nhất với máy chủ, thay vì yêu cầu 1000 yêu cầu POST riêng biệt và 500 DELETE.

Có ai có bất kỳ thông tin nào về các phương pháp hoặc quy ước tốt nhất để đạt được điều này không? Suy nghĩ hiện tại của tôi là người ta có thể PUT một đối tượng đại diện cho sự thay đổi thành URI bộ sưu tập, nhưng điều này có vẻ mâu thuẫn với HTTP 1.1 RFC, có vẻ như gợi ý rằng dữ liệu được gửi trong yêu cầu PUT cần được giải thích một cách độc lập từ dữ liệu đã có tại URI. Điều này ngụ ý rằng khách hàng sẽ phải gửi một mô tả đầy đủ về trạng thái mới của bộ sưu tập trong một lần, có thể lớn hơn rất nhiều so với thay đổi, hoặc thậm chí nhiều hơn khách hàng sẽ biết khi nào họ đưa ra yêu cầu.

Rõ ràng, tôi rất sẵn lòng đi chệch khỏi RFC nếu cần thiết nhưng muốn thực hiện điều này theo cách thông thường nếu có quy ước như vậy.

+0

Bạn có kiểm soát khách hàng bằng API của mình hoặc bạn có cần hỗ trợ các sản phẩm khách hàng hiện tại không? Nói cách khác: Bạn có tự do xác định ngữ nghĩa của các thực thể yêu cầu không? – mkoeller

Trả lời

2

Bạn nên sử dụng AtomPub. Nó được thiết kế đặc biệt để quản lý các bộ sưu tập thông qua HTTP. Thậm chí có thể có triển khai cho ngôn ngữ bạn chọn.

+2

Trên thực tế, AtomPub chỉ định nghĩa thêm các mục đơn vào bộ sưu tập và loại bỏ chúng. Vì vậy, tôi sẽ không gọi đó là "thiết kế đặc biệt để quản lý bộ sưu tập". –

2

Đối với POST, ít nhất, có vẻ như bạn sẽ có thể POST vào URL danh sách và yêu cầu nội dung chứa danh sách tài nguyên mới thay vì một tài nguyên mới.

1

Theo như tôi đã hiểu, REST có nghĩa là chuyển giao trạng thái chuyển trạng thái, vì vậy bạn nên chuyển trạng thái từ máy khách sang máy chủ.

Nếu điều đó có nghĩa là quá nhiều dữ liệu đi qua lại, có lẽ bạn cần thay đổi cách trình bày của mình. Một cấu trúc collectionChange sẽ làm việc, với một loạt các xóa (theo id) và các bổ sung (với các biểu diễn xml đầy đủ nhúng), được gửi tới một URL giao diện xử lý. Việc thực hiện giao diện có thể chọn phương pháp riêng của nó để xóa và bổ sung phía máy chủ.

Phiên bản thuần túy nhất có thể là xác định các mục theo URL và bộ sưu tập chứa một chuỗi URL. Bộ sưu tập mới có thể là PUT sau khi thay đổi bởi máy khách, theo sau là một loạt các PUT của các mục được thêm vào, và có lẽ một loạt các xóa nếu bạn muốn thực sự loại bỏ các mục khỏi máy chủ thay vì chỉ xóa chúng khỏi danh sách đó.

0

Bạn có thể giới thiệu meta-đại diện của các yếu tố bộ sưu tập hiện có mà không cần toàn bộ trạng thái của họ chuyển giao, vì vậy trong một số mã trừu tượng cập nhật của bạn có thể trông như thế này:

{existing elements 1-100} 
{new element foo with values "bar", "baz"} 
{existing element 105} 
{new element foobar with values "bar", "foo"} 
{existing elements 110-200}

Thêm (và sửa đổi) các yếu tố là được thực hiện bằng cách xác định giá trị của chúng, xóa các phần tử được thực hiện bằng cách không đề cập đến nó bộ sưu tập mới và các phần tử sắp xếp lại được thực hiện bằng cách xác định thứ tự mới (nếu thứ tự được lưu trữ).

Bằng cách này bạn có thể dễ dàng trình bày toàn bộ bộ sưu tập mới mà không phải truyền lại toàn bộ nội dung. Sử dụng tiêu đề If-Unmodified-Since đảm bảo rằng ý tưởng của bạn về nội dung thực sự phù hợp với ý tưởng của máy chủ (để bạn không vô tình xóa các yếu tố mà bạn không biết khi yêu cầu được gửi).

+0

Nếu tôi hiểu định dạng cập nhật được đề xuất của bạn một cách chính xác, điều này có bất lợi khi không phải là idempotent, vì bạn tham khảo các phần tử thu thập theo cách tương đối (bằng cách sử dụng các chỉ mục) - nếu bản cập nhật là 'PUT' đến máy chủ hai lần (có thể bởi tai nạn), bạn có thể kết thúc với một bộ sưu tập bị hỏng; ví dụ. yếu tố số 105 sẽ là một yếu tố khác lần thứ hai xung quanh lần đầu tiên; các yếu tố khác nhau 101-104 sẽ bị xóa lần thứ 2 xung quanh. – stakx

59

Bạn có thể muốn nghĩ về nhiệm vụ thay đổi dưới dạng tài nguyên trong chính nó. Vì vậy, bạn thực sự PUT-ing một đối tượng duy nhất, đó là một đối tượng Cập nhật dữ liệu hàng loạt. Có thể nó có tên, chủ sở hữu và các blob lớn của CSV, XML, v.v. cần phải được phân tích cú pháp và thực thi. Trong trường hợp CSV, bạn cũng có thể muốn xác định loại đối tượng nào được thể hiện trong dữ liệu CSV.

Danh sách công việc, thêm công việc, xem trạng thái công việc, cập nhật công việc (có thể để bắt đầu/dừng công việc), xóa công việc (dừng nó nếu nó đang chạy). Thiết kế REST API.

Khi bạn đã thực hiện điều này, bạn có thể dễ dàng thêm các loại dữ liệu khác nhau mà trình cập nhật dữ liệu hàng loạt của bạn có thể xử lý, thậm chí có thể trộn lẫn với nhau trong cùng một tác vụ. Không cần phải có cùng một API trùng lặp trên tất cả các ứng dụng của bạn cho từng loại điều bạn muốn nhập, nói cách khác.

Điều này cũng tự vay rất dễ dàng để thực hiện tác vụ nền. Trong trường hợp đó, bạn có thể muốn thêm các trường vào các đối tượng nhiệm vụ riêng lẻ cho phép trình khách API chỉ định cách họ muốn được thông báo (URL họ muốn bạn GET khi nó được thực hiện hoặc gửi cho họ một e-mail, v.v.) .

+2

Điều này cần được kiểm tra là câu trả lời! – HDave

+2

Câu trả lời hay. Nếu bạn muốn áp dụng một hoạt động cho một tập hợp lớn các tài nguyên và bạn đang chọn chúng bằng cách sử dụng các điều kiện lọc, bạn có thể chuyển sang tác vụ thay đổi một đối tượng có các điều kiện lọc. –

+2

Mặc dù hợp lý để tránh "chatty" DELETEs, nó đang rơi trở lại RPC tâm lý ... Có lẽ nó là khả thi để GET bộ sưu tập, loại bỏ tất cả những điều bạn muốn xóa, sau đó PUT bộ sưu tập (sử dụng 409 trạng thái phản ứng để phát hiện chủng tộc điều kiện với các công cụ sửa đổi đồng thời). Tính khả thi của điều này sẽ giảm nếu GET được phân trang, trong trường hợp đó, PATCH có lẽ là lựa chọn đúng đắn. – delitescere

8

Có, PUT tạo/ghi đè, nhưng không cập nhật một phần.

Nếu bạn cần ngữ nghĩa cập nhật từng phần, hãy sử dụng PATCH. Xem http://greenbytes.de/tech/webdav/draft-dusseault-http-patch-14.html.

+0

Điều này có ý nghĩa nhất đối với tôi. Tuy nhiên, sau khi tìm kiếm trên web trong vài giờ, điều này dường như không phải là quan điểm thường được tổ chức. Hầu hết các nhà phát triển dường như nghĩ rằng PATCH không có ý nghĩa đối với một bộ sưu tập. –

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