Katakanlah Anda memiliki semacam struktur data, yang bertahan dalam beberapa jenis database. Untuk kesederhanaan, sebut saja struktur data ini Person
. Anda sekarang ditugaskan untuk merancang API CRUD, yang memungkinkan aplikasi lain untuk membuat, membaca, memperbarui, dan menghapus Person
. Untuk mempermudah, mari kita asumsikan bahwa API ini diakses melalui beberapa jenis layanan web.
Untuk bagian C, R dan D dari CRUD, desainnya sederhana. Saya akan menggunakan notasi fungsional mirip C # - implementasinya bisa SOAP, REST / JSON, atau yang lain:
class Person {
string Name;
DateTime? DateOfBirth;
...
}
Identifier CreatePerson(Person);
Person GetPerson(Identifier);
void DeletePerson(Identifier);
Bagaimana dengan pembaruan? Hal yang wajar untuk dilakukan adalah
void UpdatePerson(Identifier, Person);
tetapi bagaimana Anda menentukan bidang mana yangPerson
akan diperbarui?
Solusi yang dapat saya berikan:
Anda selalu dapat meminta Orang yang lengkap untuk lulus, yaitu klien akan melakukan sesuatu seperti ini untuk memperbarui tanggal lahir:
p = GetPerson(id); p.DateOfBirth = ...; UpdatePerson(id, p);
Namun, itu akan membutuhkan semacam konsistensi transaksional atau penguncian antara Dapatkan dan Pembaruan; jika tidak, Anda bisa menimpa beberapa perubahan lain yang dilakukan secara paralel oleh beberapa klien lain. Ini akan membuat API jauh lebih rumit. Selain itu, ini rawan kesalahan, karena pseudo-code berikut (dengan asumsi bahasa klien dengan dukungan JSON)
UpdatePerson(id, { "DateOfBirth": "2015-01-01" });
- yang terlihat benar - tidak hanya akan mengubah DateOfBirth tetapi juga mengatur ulang semua bidang lainnya menjadi nol.
Anda dapat mengabaikan semua bidang yang ada
null
. Namun, bagaimana Anda kemudian membuat perbedaan antara tidak berubahDateOfBirth
dan dengan sengaja mengubahnya menjadi nol ?Ubah tanda tangan ke
void UpdatePerson(Identifier, Person, ListOfFieldNamesToUpdate)
.Ubah tanda tangan ke
void UpdatePerson(Identifier, ListOfFieldValuePairs)
.Gunakan beberapa fitur protokol transmisi: Misalnya, Anda bisa mengabaikan semua bidang yang tidak terkandung dalam representasi JSON dari Orang tersebut. Namun, itu biasanya membutuhkan penguraian JSON sendiri dan tidak dapat menggunakan fitur built-in perpustakaan Anda (misalnya WCF).
Tidak ada solusi yang tampak sangat elegan bagi saya. Tentunya, ini adalah masalah umum, jadi apa solusi praktik terbaik yang digunakan oleh semua orang?
Person
contoh yang baru dibuat yang masih belum ada, dan dalam hal pengidentifikasi diputuskan sebagai bagian dari mekanisme ketekunan, biarkan saja nol. Adapun jawabannya, JPA menggunakan nomor versi; jika Anda membaca versi 23, ketika Anda memperbarui item jika versi dalam DB adalah 24 penulisan gagal.