Làm thế nào tốt nhất để bạn đại diện cho một đồng bộ hai chiều trong api REST?


23

Giả sử một hệ thống có Ứng dụng web có tài nguyên và tham chiếu đến ứng dụng từ xa với tài nguyên tương tự khác, làm thế nào để bạn thể hiện hành động đồng bộ hai chiều đồng bộ hóa tài nguyên 'cục bộ' với tài nguyên 'từ xa'?

Thí dụ:

Tôi có một API đại diện cho một danh sách việc cần làm.

NHẬN / POST / PUT / DELETE / todos /, v.v.

API đó có thể tham chiếu các dịch vụ TODO từ xa.

NHẬN / POST / PUT / DELETE / todo_service /, v.v.

Tôi có thể thao tác mã thông báo từ dịch vụ từ xa thông qua API của mình dưới dạng proxy thông qua

NHẬN / POST / PUT / DELETE / todo_service / abc123 /, v.v.

Tôi muốn khả năng thực hiện đồng bộ hai chiều giữa một bộ mã thông báo cục bộ và bộ TODOS từ xa.

Theo cách rpc, người ta có thể làm

POST / todo_service / abc123 / đồng bộ hóa /

Nhưng, trong ý tưởng "động từ là xấu", có cách nào tốt hơn để đại diện cho hành động này?


4
Tôi nghĩ rằng một thiết kế API tốt hoàn toàn phụ thuộc vào sự hiểu biết rất cụ thể về ý nghĩa của bạn khi đồng bộ hóa. "Đồng bộ hóa" của hai nguồn dữ liệu thường là một vấn đề rất phức tạp, rất dễ để quá mức nhưng rất khó để suy nghĩ trong tất cả các hàm ý của nó. Làm cho nó trở thành một đồng bộ "hai chiều", và đột nhiên độ khó cao hơn nhiều. Bắt đầu bằng cách suy nghĩ thông qua các câu hỏi rất khó đưa ra.
Adam Crossland

Phải - giả sử thuật toán đồng bộ được thiết kế và hoạt động trong API "cấp độ mã" - làm cách nào để hiển thị điều này thông qua REST. Đồng bộ một chiều có vẻ dễ diễn đạt hơn nhiều: Tôi GET /todo/1/POSTnó với /todo_services/abc123/ Nhưng, cách 2 - Tôi không lấy dữ liệu và PUTting nó thành tài nguyên, hành động tôi thực sự dẫn đến việc sửa đổi tiềm năng của hai tài nguyên. Tôi đoán rằng tôi có thể quay trở lại khi có "việc đồng bộ hóa" là tài nguyên POST /todo_synchronizations/ {"todos":["/todo/1/","/todo_services/abc123/1"],"schedule":"now"}
Edward M Smith

Chúng tôi vẫn có một vấn đề giỏ hàng trước khi ngựa. Quan điểm của tôi là bạn không thể cho rằng đồng bộ hóa chỉ hoạt động và thiết kế API. Việc thiết kế API sẽ được thúc đẩy bởi nhiều mối quan tâm về chính xác cách thức thuật toán đồng bộ hóa hoạt động.
Adam Crossland

Điều đó có khả năng phơi bày kết quả hữu ích: GET /todo_synchronizations/1=>{"todos":["/todo/1/","/todo_services/abc123/1"],"schedule":"now","ran_at":"datetime","result":"success"}
Edward M Smith

2
Tôi đồng ý với @Adam. Bạn có biết làm thế nào bạn sẽ thực hiện đồng bộ hóa của bạn? Làm thế nào bạn xử lý các thay đổi? Bạn chỉ đơn giản là có hai bộ vật phẩm mà bạn muốn điều hòa hoặc bạn có nhật ký các hành động khiến hai bộ phân kỳ kể từ lần đồng bộ hóa cuối cùng không? Lý do tôi hỏi là có thể khó để phát hiện thêm và xóa (bất kể REST). Nếu bạn có phía máy chủ đối tượng và không có phía máy khách, bạn phải tự hỏi: "Máy khách đã xóa nó hay máy chủ đã tạo ra nó?" Chỉ khi bạn biết chính xác cách "tài nguyên" hành xử, bạn mới có thể biểu diễn chính xác nó trong REST.
Raymond Saltrelli

Câu trả lời:


17

Tài nguyên ở đâu và là gì?

REST là tất cả về việc giải quyết các tài nguyên theo cách không trạng thái, có thể khám phá. Nó không phải được triển khai qua HTTP, cũng không phải dựa vào JSON hoặc XML, mặc dù chúng tôi khuyến nghị sử dụng định dạng dữ liệu hypermedia (xem nguyên tắc HATEOAS ) vì các liên kết và id là mong muốn.

Vì vậy, câu hỏi trở thành: Làm thế nào một người nghĩ về đồng bộ hóa về tài nguyên?

Đồng bộ hai chiều là gì? **

Đồng bộ hai chiều là quá trình cập nhật các tài nguyên có trên biểu đồ các nút để khi kết thúc quá trình, tất cả các nút đã cập nhật tài nguyên của chúng theo các quy tắc chi phối các tài nguyên đó. Thông thường, điều này được hiểu là tất cả các nút sẽ có phiên bản mới nhất của tài nguyên như hiện diện trong biểu đồ. Trong trường hợp đơn giản nhất, đồ thị bao gồm hai nút: cục bộ và từ xa. Địa phương bắt đầu đồng bộ.

Vì vậy, tài nguyên chính cần được xử lý là nhật ký giao dịch và do đó, quy trình đồng bộ hóa có thể giống như thế này đối với bộ sưu tập "vật phẩm" trong HTTP:

Bước 1 - Lấy địa chỉ nhật ký giao dịch

Địa phương: GET /remotehost/items/transactions?earliest=2000-01-01T12:34:56.789Z

Từ xa: 200 OK với phần thân chứa nhật ký giao dịch chứa các trường tương tự như thế này.

  • itemId - UUID để cung cấp khóa chính được chia sẻ

  • updatedAt - dấu thời gian để cung cấp điểm phối hợp khi dữ liệu được cập nhật lần cuối (giả sử rằng không cần lịch sử sửa đổi)

  • fingerprint- hàm băm SHA1 của nội dung dữ liệu để so sánh nhanh nếu hết updateAtvài giây

  • itemURI - một URI đầy đủ cho mục để cho phép truy xuất sau

Bước 2 - Local so sánh nhật ký giao dịch từ xa với nhật ký giao dịch từ xa

Đây là ứng dụng của các quy tắc kinh doanh về cách đồng bộ hóa. Thông thường, itemIdsẽ xác định tài nguyên cục bộ, sau đó so sánh dấu vân tay. Nếu có một sự khác biệt thì một so sánh updatedAtđược thực hiện. Nếu chúng quá gần để gọi thì sẽ cần đưa ra quyết định để kéo dựa trên nút khác (có lẽ nó quan trọng hơn) hoặc đẩy sang nút khác (nút này quan trọng hơn). Nếu tài nguyên từ xa không có mặt cục bộ thì một mục đẩy được thực hiện (phần này chứa dữ liệu thực tế để chèn / cập nhật). Bất kỳ tài nguyên cục bộ nào không có trong nhật ký giao dịch từ xa được coi là không thay đổi.

Các yêu cầu kéo được thực hiện đối với nút từ xa để dữ liệu tồn tại cục bộ bằng cách sử dụng itemURI. Chúng không được áp dụng tại địa phương cho đến sau này.

Bước 3 - Đẩy nhật ký giao dịch đồng bộ cục bộ vào từ xa

Local: PUT /remotehost/items/transactions với phần thân chứa nhật ký giao dịch đồng bộ cục bộ.

Nút từ xa có thể xử lý việc này một cách đồng bộ (nếu nhỏ và nhanh) hoặc không đồng bộ (nghĩ 202 CHẤP NHẬN ) nếu nó có thể phải chịu nhiều chi phí. Giả sử một hoạt động đồng bộ, thì kết quả sẽ là 200 OK hoặc 409 CONFLICT tùy thuộc vào thành công hay thất bại. Trong trường hợp 409 CONFLICT , sau đó quá trình phải được bắt đầu lại do đã xảy ra lỗi khóa lạc quan tại nút từ xa (ai đó đã thay đổi dữ liệu trong quá trình đồng bộ hóa). Các cập nhật từ xa được xử lý theo giao dịch ứng dụng riêng của họ.

Bước 4 - Cập nhật cục bộ

Dữ liệu được kéo trong Bước 2 được áp dụng cục bộ theo giao dịch ứng dụng.

Mặc dù ở trên là không hoàn hảo (có một số tình huống mà cục bộ và từ xa có thể gặp rắc rối và có dữ liệu kéo từ xa cục bộ có thể hiệu quả hơn so với việc nhét nó vào một PUT lớn), nó chứng minh làm thế nào REST có thể được sử dụng trong một bi- quy trình đồng bộ hóa định hướng.


6

Tôi sẽ xem xét một hoạt động đồng bộ hóa như một tài nguyên có thể được truy cập (GET) hoặc được tạo (POST). Với ý nghĩ đó, URL API có thể là:

/todo_services/abc123/synchronization

(Gọi nó là "đồng bộ hóa", không phải "đồng bộ hóa" để làm cho nó rõ ràng không phải là một động từ)

Sau đó làm:

POST /todo_services/abc123/synchronization

Để bắt đầu đồng bộ hóa. Vì hoạt động đồng bộ hóa là tài nguyên, cuộc gọi này có khả năng trả về ID mà sau đó có thể được sử dụng để kiểm tra trạng thái của hoạt động:

GET /todo_services/abc123/synchronization?id=12345

3
Câu trả lời đơn giản này là câu trả lời. Biến động từ của bạn thành danh từ và di chuyển ...
HDave 17/03/2015

5

Đây là một vấn đề khó khăn. Tôi không tin REST là một mức thích hợp để thực hiện đồng bộ hóa. Đồng bộ hóa mạnh mẽ về cơ bản sẽ cần phải là một giao dịch phân tán. REST không phải là công cụ cho công việc đó.

(Giả định: bằng cách "đồng bộ hóa", bạn đang ám chỉ rằng một trong hai tài nguyên có thể thay đổi độc lập với tài nguyên khác bất cứ lúc nào và bạn muốn có khả năng sắp xếp lại chúng mà không mất cập nhật.)

Bạn có thể muốn xem xét việc biến một "chủ" và một "nô lệ" khác để bạn có thể tự tin đóng băng nô lệ theo định kỳ với dữ liệu từ chủ.

Bạn cũng có thể xem xét Microsoft Sync Framework nếu bạn thực sự cần hỗ trợ các cửa hàng dữ liệu thay đổi độc lập. Điều này sẽ không hoạt động thông qua REST, nhưng đằng sau hậu trường.


5
+1 cho "vấn đề khó". Đồng bộ hóa hai chiều là một trong những điều mà bạn không nhận ra nó khó đến mức nào cho đến khi bạn chìm sâu trong bùn.
Dan Ray

2

Apache CouchDB là một cơ sở dữ liệu dựa trên REST, HTTP và JSON. Các nhà phát triển thực hiện các hoạt động CRUD cơ bản qua HTTP. Nó cũng cung cấp một cơ chế sao chép ngang hàng chỉ sử dụng các phương thức HTTP.

Để cung cấp bản sao này, CouchDB cần có một số quy ước dành riêng cho CouchDB. Không ai trong số này trái ngược với REST. Nó cung cấp cho mỗi tài liệu (đó là tài nguyên REST trong cơ sở dữ liệu) với số sửa đổi . Đây là một phần của biểu diễn JSON của tài liệu đó, nhưng cũng nằm trong tiêu đề ETag HTTP. Mỗi cơ sở dữ liệu cũng có một số thứ tự cho phép theo dõi các thay đổi đối với toàn bộ cơ sở dữ liệu.

Để giải quyết xung đột , họ chỉ cần lưu ý rằng một tài liệu bị xung đột và giữ lại các phiên bản bị xung đột, để lại cho các nhà phát triển sử dụng cơ sở dữ liệu để cung cấp thuật toán giải quyết xung đột.

Bạn có thể sử dụng CouchDB làm API REST, sẽ cung cấp cho bạn đồng bộ hóa ngoài hộp hoặc xem cách nó cung cấp bản sao để cung cấp một điểm khởi đầu để tạo thuật toán của riêng bạn.


Tôi yêu CouchDB và đó là người kế nhiệm CouchBase + SyncGateway. +1
Leonid Usov

-1

Bạn có thể giải quyết vấn đề "động từ là xấu" bằng cách đổi tên đơn giản - sử dụng "cập nhật" thay vì "đồng bộ hóa".

Quá trình đồng bộ hóa thực sự đang gửi một danh sách các bản cập nhật cục bộ được thực hiện kể từ lần đồng bộ hóa cuối cùng và nhận được một danh sách các bản cập nhật được thực hiện trên máy chủ trong cùng thời gian đó.

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.