Giả sử bạn có một số loại cấu trúc dữ liệu, được duy trì trong một số loại cơ sở dữ liệu. Để đơn giản, hãy gọi cấu trúc dữ liệu này Person
. Bây giờ bạn có nhiệm vụ thiết kế API CRUD, cho phép các ứng dụng khác tạo, đọc, cập nhật và xóa Person
s. Để đơn giản, hãy giả sử rằng API này được truy cập thông qua một số loại dịch vụ web.
Đối với các phần C, R và D của CRUD, thiết kế rất đơn giản. Tôi sẽ sử dụng ký hiệu chức năng giống như C # - việc triển khai có thể là SOAP, REST / JSON hoặc một cái gì đó khác:
class Person {
string Name;
DateTime? DateOfBirth;
...
}
Identifier CreatePerson(Person);
Person GetPerson(Identifier);
void DeletePerson(Identifier);
Còn cập nhật thì sao? Điều tự nhiên phải làm là
void UpdatePerson(Identifier, Person);
nhưng làm thế nào bạn sẽ xác định được lĩnh vực Person
để cập nhật?
Các giải pháp mà tôi có thể đưa ra:
Bạn luôn có thể yêu cầu một Người hoàn thành được thông qua, tức là khách hàng sẽ làm một cái gì đó như thế này để cập nhật ngày sinh:
p = GetPerson(id); p.DateOfBirth = ...; UpdatePerson(id, p);
Tuy nhiên, điều đó sẽ yêu cầu một số loại nhất quán giao dịch hoặc khóa giữa Nhận và Cập nhật; mặt khác, bạn có thể ghi đè lên một số thay đổi khác được thực hiện song song bởi một số khách hàng khác. Điều này sẽ làm cho API phức tạp hơn nhiều. Ngoài ra, nó dễ bị lỗi, vì mã giả sau đây (giả sử ngôn ngữ máy khách có hỗ trợ JSON)
UpdatePerson(id, { "DateOfBirth": "2015-01-01" });
- có vẻ đúng - sẽ không chỉ thay đổi DateOfBirth mà còn đặt lại tất cả các trường khác thành null.
Bạn có thể bỏ qua tất cả các lĩnh vực đó
null
. Tuy nhiên, làm thế nào bạn sẽ tạo ra sự khác biệt giữa việc không thay đổiDateOfBirth
và cố tình thay đổi nó thành null ?Thay đổi chữ ký thành
void UpdatePerson(Identifier, Person, ListOfFieldNamesToUpdate)
.Thay đổi chữ ký thành
void UpdatePerson(Identifier, ListOfFieldValuePairs)
.Sử dụng một số tính năng của giao thức truyền: Ví dụ: bạn có thể bỏ qua tất cả các trường không có trong biểu diễn JSON của Người. Tuy nhiên, điều đó thường yêu cầu tự phân tích JSON và không thể sử dụng các tính năng tích hợp trong thư viện của bạn (ví dụ WCF).
Không có giải pháp nào có vẻ thực sự thanh lịch với tôi. Chắc chắn, đây là một vấn đề phổ biến, vậy giải pháp thực hành tốt nhất được mọi người sử dụng là gì?
Person
trường hợp mới được tạo mà vẫn không được duy trì và trong trường hợp định danh được quyết định như là một phần của cơ chế lưu giữ lâu dài, chỉ cần để nó thành null. Đối với câu trả lời, JPA sử dụng số phiên bản; nếu bạn đọc phiên bản 23, khi bạn cập nhật mục nếu phiên bản trong DB là 24 thì việc ghi không thành công.