Pertanyaan Validator aturan bisnis dan pengendali perintah dalam CQRS


Saya baru mengenal CQRS dan saya mengikat untuk memaknai validasi aturan bisnis dalam sisi tulis (domain). Saya tahu bahwa validasi sisi klien harus dilakukan dalam hal tanggal yang valid (bidang wajib, panjang string, email yang valid, dll) dan validasi aturan bisnis / domain bisnis yang terkait harus dilakukan di sisi domain. Sebenarnya, aturan validasi sisi klien yang sama juga harus diterapkan pada perintah di domain karena kami tidak mempercayai pengguna.

Jadi, kami memiliki perintah yang valid (AddEmailToCustomer) dan pengendali perintah dipanggil pada perintah. Berikut ini pendekatan saya untuk validasi.

  1. Buat contoh dari dua validator perintah di pengendali perintah.
  2. Yang pertama memvalidasi data perintah yang sama dengan validasi sisi klien (bidang wajib, email yang valid, dll.)
  3. Validator kedua memvalidasi data berdasarkan logika dalam validator kedua. Sesuatu seperti "apakah pelanggan ini aktif", atau apa pun. Saya tahu surel yang berubah tidak sesuai di sini tetapi itu tidak penting. Yang penting ada validasi bisnis di sini.
  4. Kami melihat ValidationResult yang dikembalikan oleh Validator.Validate (ICommand cmd) dan kami menemukan ada kesalahan
  5. Kami tidak akan mendapatkan pelanggan dari repositori untuk memanggil metode UpdateEmail pada AR. Jadi apa yang kita lakukan saat ini?

Apakah saya melempar dan mengecualikan dalam command handler dan menambahkan kesalahan-kesalahan ini di sana? Apakah saya mengirim perintah ke antrean kesalahan atau di tempat lain? Apakah saya merespons dengan sesuatu seperti Bus.Balas dan kembalikan kode kesalahan? Jika demikian, apa yang harus saya lakukan dengan pesan kesalahan itu? Bagaimana saya mengkomunikasikan kesalahan ini kepada pengguna? Saya tahu saya dapat mengirim email kepada mereka nanti tetapi dalam skenario web saya dapat mengirim id permintaan dalam perintah (atau menggunakan id pesan), dan jajak pendapat untuk respon dengan id permintaan dan menampilkan pesan kesalahan kepada pengguna.

Bimbingan Anda sangat dihargai.

Terima kasih


32
2018-03-22 22:33


asal


Jawaban:


Sangat penting untuk mengetahui perintah itu bisa ditolak setelah dikirim ke handler.

Paling tidak, Anda bisa menghadapi pelanggaran konkurensi yang tidak dapat dideteksi sampai akar agregat disentuh.

Tetapi juga, validasi yang dapat terjadi di luar entitas adalah validasi sederhana. Tidak hanya panjang string, rentang numerik, pencocokan regex, dll. Tetapi juga validasi yang dapat memuaskan melalui kueri atau tampilan, seperti keunikan dalam koleksi. Penting untuk diingat bahwa validasi yang melibatkan pandangan terwujud mungkin akhirnya konsisten, yang merupakan alasan lain perintah dapat ditolak dari agregat, di dalam pengendali perintah. Yang mengatakan, untuk mendahului situasi, saya sering menggunakan model baca untuk menggerakkan pilihan UI yang hanya memungkinkan tindakan yang valid.

Validasi itu tidak bisa terjadi di luar entitas adalah validasi logika bisnis Anda. Validasi ini tergantung pada konteks di mana ia dijalankan (lihat CQRS Klarifikasi Udi Dahan).

Logika bisnis seharusnya tidak berada di layanan validasi terpisah. Itu harus di domain Anda.

Juga, saya berpendapat bahwa validasi yang terjadi di UI harus diperiksa ulang bukan di pengendali perintah, tetapi di domain juga. Validasi yang ada untuk mencegah korupsi ke domain - jika tidak dilakukan di luar domain maka domain masih tunduk pada parameter yang tidak valid.

Menggunakan penangan perintah untuk menggandakan validasi ini hanya sebuah konvensi. Jika tidak ada front end yang mengirim perintah, maka itu adalah duplikat yang tidak berguna. Jika ada beberapa ujung depan, itu hanya satu pilihan tempat untuk menempatkan validasi duplikat yang diperlukan, dan dalam kasus-kasus itu saya lebih suka untuk menanganinya di domain.

Terakhir, Anda perlu menggelembungkan perintah yang ditolak dari dalam handler. Saya mencapai ini dengan pengecualian sebanyak mungkin.


41
2018-03-23 05:40