The Problem With U
Tentu saja saya tidak ada masalah denganmu yang entah bagaimana caranya masuk ke blog ini, "U" yang saya maksud di judul di atas adalah "U" dalam operasional "CRUD".
CRUD yang merupakan singkatan dari Create Read Update Delete sering dianggap prosedur yang sederhana, bahkan beberapa mungkin bilang "tutup mata juga kelar" tapi ternyata tidak semudah itu, apalagi si U, kenapa? Izinkan saya mengutarakan opini (yang walaupun tidak diizinkan tetap akan saya tulis toh ini blog saya).
Dalam operasional CRUD selain U itu cukup mudah ditebak, Untuk operasi "Create" sudah jelas dari 0 --> 1, dari tidak ada menjadi ada. Selanjutnya "Delete" adalah sebaliknya dari 1 --> 0, dari ada menjadi tiada, jelas. "Read" apalagi, tidak ada perubahan state dari data hanya persoalan bagaimana cara menampilkan kepada user, ribet tapi umumnya jelas. "Update" lain lagi, dia tidak hanya mampu mengubah 1 --> 2 atau 1 -->3, tapi bisa jadi mengubah 1 --> 1a. Lalu kenapa Update dirasa bermasalah? Mari saya share pengalaman saya dulu dan sekarang.
Full Body Update
Saya tidak tahu istilah yang tepat tapi ini gambarannya, misal kita punya data user seperti ini di database:
id: 1
name: John
age: 18
status: active
Dalam waktu yang bersamaan dua orang membuka satu halaman update yang sama, baik pengguna pertama dan kedua akan mendapatkan informasi yang sama dengan yang di database.
Lalu katakanlah pengguna pertama mengubah namanya menjadi "Sam" dan menekan tombol simpan, maka data di database menjadi:
id: 1
name: Sam
age: 18
status: active
Di database data sudah berubah, tapi di halaman update pengguna nomor 2 masih terpampang data awal yang namanya "John", lalu si pengguna 2 ini mengubah status menjadi "inactive" dan menekan tombol save, kira-kira apa yang terjadi jika sistem update yang dilakukan adalah mengirim semua full body form? Yang terjadi adalah data di database berubah menjadi
id: 1
name: John
age: 18
status: inactive
Apakah itu bug? Tergantung kita mendefinisikan bug tapi yang jelas fungsi update yang dibuat bekerja dan berhasil mengubah data. Bagaimana mengatasi isu ini?
Sanitasi Input
Cara yang dulu saya lakukan adalah dengan menentukan data yang dikirim ke backend dari depan.
ini adalah cara saat saya dulu menggunakan nuxt, seharusnya sama saja dengan fw frontend apapun
Jadi saya buat dua state
yang berbeda, pertama adalah display_state
yang fungsinya menampung data yang diambil dari database/api, dan kedua adalah payload_state
yang merupakan data yang akan saya kirimkan ke backend.
Jadi ketika pengguna pertama mengubah nama saja, maka payload yang akan saya kirimkan hanya nama saja bukan semua data
{
"payload" : {
"name": "Sam"
}
}
Di backend kami menggunakan method patch sehingga ketika dikirimkan seperti di atas yang diubah hanya field name saja, dan ketika pengguna 2 mengubah status maka
{
"payload" : {
"status": "inactive"
}
}
Jadi intinya adalah saya hanya mengirimkan informasi yang berbeda dengan display_state
Tapi cara ini hanya mengurangi kejadian isu yang diceritakan di atas, isu di atas akan terjadi jika pengguna pertama dan kedua secara kebetulan mengubah field sama, lalu bagaimana mencegah itu?
Updated Time
Saya ada kebiasaan selalu membuat secara default sebuah field date_created
& date_updated
jadi data awal akan seperti ini
id: 1
name: John
age: 18
status: active
date_created: 2023-01-01 13:00:00
date_updated: 2023-05-01 19:30:25
Poin pentingnya adalah, date_updated
harus dikirmkan baik dari BE ke depan agar nantinya FE akan bisa mengirimkan ulang yang akan digunakan oleh BE untuk melakukan validasi, contoh pseudocode nya menjadi seperti ini
Misal, BE sudah mengirimkan informasi semuanya sesuai yang di database, maka FE wajib mengirimkan semua data yang dia ubah sekaligus dengan date_updated
sehingga di BE akan ada validasi dan kode seperti ini
func update(request request) {
getData = GetDetailFromDB(request.id)
if getData.DateUpdated != request.DateUpdated {
return "error: Form is outdated"
}
// if ok, continue to update
}
Pseudocode di atas akan mengecek untuk memastikan saat mengubah data itu adalah kondisi terbaru, sehingga dalam kasus di atas:
Pengguna pertama akan sukses mengubah data karena lolos validasi dan akan mengubah date_updated
dari 2023-05-01 19:30:25 ke tanggal saat dia ubah misal 2023-05-02 13:15:00
Pengguna dua akan gagal mengubah data dan terkena error Form is outdated
karena ketika dia mengirimkan perubahan data dia mengubah data yang tanggal 2023-05-01 19:30:25 sedangkan data di database sudah 2023-05-02 13:15:00. Sehingga pengguna 2 wajib reload atau refetch data.
Validasi sederhana di atas cukup membantu untuk data tidak saling tumpang tindih secara tidak sengaja.
Ada satu cara lagi yang sebenarnya bisa jadi jauh lebih baik yaitu memisahkan perubahan data ke masing-masih endpoint jadi tidak satu endpoint untuk mengubah semuanya, misal untuk ubah status harus menekan tombol ubah status, untuk ubah yang lainnya tekan tombol yang berbeda, tapi itu untuk tulisan lain lagi.