Bagikan melalui


Menerapkan pola CQRS dan DDD yang disederhanakan dalam layanan mikro

Tip

Konten ini adalah kutipan dari eBook, .NET Microservices Architecture for Containerized .NET Applications, tersedia di .NET Docs atau sebagai PDF yang dapat diunduh gratis dan dapat dibaca secara offline.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

CQRS adalah pola arsitektur yang memisahkan model untuk membaca dan menulis data. Istilah terkait Command Query Separation (CQS) awalnya didefinisikan oleh Bertrand Meyer dalam bukunya Object-Oriented Software Construction. Ide dasarnya adalah Anda dapat membagi operasi sistem menjadi dua kategori yang dipisahkan dengan tajam:

  • Kueri. Kueri ini mengembalikan hasil dan tidak mengubah status sistem, dan bebas dari efek samping.

  • Perintah. Perintah yang mengubah status sistem.

CQS adalah konsep sederhana: ini adalah metode dalam objek yang sama yaitu kueri atau perintah. Setiap metode mengembalikan status atau mengubah status, tetapi tidak keduanya. Bahkan objek pola repositori tunggal dapat mematuhi CQS. CQS dapat dianggap sebagai prinsip dasar untuk CQRS.

Command and Query Responsibility Segregation (CQRS) diperkenalkan oleh Greg Young dan sangat dipromosikan oleh Udi Dahan dan lainnya. Ini didasarkan pada prinsip CQS, meskipun lebih rinci. Ini dapat dianggap sebagai pola berdasarkan perintah dan peristiwa ditambah secara opsional pada pesan asinkron. Dalam banyak kasus, CQRS terkait dengan skenario yang lebih maju, seperti memiliki database fisik yang berbeda untuk membaca (kueri) daripada untuk menulis (pembaruan). Selain itu, sistem CQRS yang lebih berkembang mungkin menerapkan Event-Sourcing (ES) untuk database pembaruan Anda, sehingga Anda hanya akan menyimpan peristiwa dalam model domain alih-alih menyimpan data status saat ini. Tetapi, pendekatan ini tidak digunakan dalam panduan ini. Panduan ini menggunakan pendekatan CQRS paling sederhana, terdiri dari hanya memisahkan kueri dari perintah.

Aspek pemisahan CQRS dicapai dengan mengelompokkan operasi kueri dalam satu lapisan dan perintah di lapisan lain. Setiap lapisan memiliki model datanya sendiri (perhatikan bahwa kami mengatakan model, tidak harus memiliki database yang berbeda) dan dibangun menggunakan kombinasi pola dan teknologinya sendiri. Lebih penting lagi, kedua lapisan dapat berada dalam tingkat atau layanan mikro yang sama, seperti pada contoh (memesan layanan mikro) yang digunakan untuk panduan ini. Atau mereka dapat diimplementasikan pada layanan mikro atau proses yang berbeda sehingga dapat dioptimalkan dan ditingkatkan secara terpisah tanpa memengaruhi satu sama lain.

CQRS berarti memiliki dua objek untuk operasi baca/tulis di mana dalam konteks lain ada satu. Ada alasan untuk memiliki database pembacaan yang didenormalisasi, ini dapat Anda pelajari di literatur CQRS yang lebih maju. Tetapi kami tidak menggunakan pendekatan itu di sini, di mana tujuannya adalah untuk memiliki lebih banyak fleksibilitas dalam kueri alih-alih membatasi kueri dengan batasan dari pola DDD seperti agregat.

Contoh layanan semacam ini adalah layanan mikro pemesanan dari aplikasi referensi eShopOnContainers. Layanan ini menerapkan layanan mikro berdasarkan pendekatan CQRS yang disederhanakan. Ini menggunakan satu sumber data atau database, tetapi dua model logis ditambah pola DDD untuk domain transaksional, seperti yang ditunjukkan pada Gambar 7-2.

Diagram showing a high level Simplified CQRS and DDD microservice.

Gambar 7-2. Layanan mikro berbasis CQRS dan DDD yang disederhanakan

Layanan Mikro "Pemesanan" Logis menyertakan basis data Pemesanannya, yang dapat berupa, tetapi tidak harus host Docker yang sama. Memiliki database di host Docker yang sama, bagus untuk pengembangan, tetapi tidak untuk produksi.

Lapisan aplikasi dapat menjadi API Web itu sendiri. Aspek desain yang penting di sini adalah bahwa layanan mikro telah membagi kueri dan ViewModels (model data yang dibuat khusus untuk aplikasi klien) dari perintah, model domain, dan transaksi mengikuti pola CQRS. Pendekatan ini membuat kueri tetap independen dari batasan dan batasan yang berasal dari pola DDD yang hanya masuk akal untuk transaksi dan pembaruan, seperti yang dijelaskan di bagian selanjutnya.

Sumber daya tambahan