Eventsourcing and CQRS Architecture using Golang, gRPC, NATS and Elasticsearch

Aris Haryanto
5 min readApr 3, 2021

--

Hi hi semua

kali ini saya bakal bikin tutorial tentang arsitektur Eventsourcing dan CQRS serta cara implementnya di golang menggunakan gRPC, NATS dan Elasticsearch

Haah Apaan tuuh ???..
eiits.. jangan bingung dulu tutorial ini saya buat sesimple mungkin biar mudah dipahami

mungkin beberapa dari kalian udah ada yang pernah dengar tentang Enventsourcing dan CQRS atau mungkin ada yang blum pernah dan baru tau sekarang

Oke, CQRS kita liat dari webnya www.cqrs.nu

CQRS means “Command-query responsibility segregation”. We segregate the responsibility between commands (write requests) and queries (read requests). The write requests and the read requests are handled by different objects.

dan eventsourcing sendiri kalo dari https://www.eventstore.com/blog/what-is-event-sourcing

alternative way to persist data. In contrast with state-oriented persistence that only keeps the latest version of the entity state, Event Sourcing stores each state mutation as a separate record called an event.

nah kita akan buat service deposit untuk create dan approve nya menggunakan arsitektur ini

oke langsung aja pertama yang harus kalian lakukan adalah clone repo berikut ke local kalian https://github.com/Aris-haryanto/CQRS-Architecture-With-Golang-gRPC-and-NATS

jika sudah silakan install tools2 yang dibutuhkan sesuai judulnya kita pake gRPC, NATS dan Elasticsearch

  • untuk gRPC protobufnya kalian bisa follow guide installnya disini
  • untuk NATSnya karena kita konsepnya realtime jadi kita pake NATS Streaming ya kalian bisa follow guide installnya disini
  • untuk elasticsearchnya kebetulan saya menggunakan MAC bisa ikutin guide untuk installnya disini
  • untuk library pendukung golangnya kalian perlu masuk dulu kedirectory yang tadi sudah diclone kemudian kalian ketik diterminal seperti ini
    go get -v ./...

jika sudah semua pastikan koneksi database MySQLnya sudah sesuai
kemudian jalankan semua servicenya yah

$ nats-streaming-server
$ elasticsearch
$ go run client/main.go
$ go run serives/main.go
$ go run deposit-create/main.go
$ go run deposit-approve/main.go
$ go run log/main.go

oke lanjut, disini saya gambarin flownya dulu yah
berikut adalah arsitektur yang akan kita buat dalam tutorial ini

Deposit Arsitektur

kalo kamu sudah clone reponya maka akan terlihat structure directory seperti ini

structure directory

Saya coba jelaskan fungsi dari masing-masing structure directory diatas sesuai nomer diagramnya

  1. Service Client
    service ini ada pada directory /client. disini adalah service yang menerima request dari User melalui API kemudian dilempar ke gRPC
    dibagian ini validasi harus sedetail mungkin, misal seperti pengecekan apakah data yang diinput sudah ada atau belum, pengecekan input string atau integer dan lainnya. agar mengurangi error sistem saat melakukan inserting kedatabase. kalaupun ada yang terlewat kita bisa melakukan push notif ke user bahwa input yang dia masukan salah dan meminta mereka input ulang, tapi ini wasting time! sebisa mungkin kita harus cegah ini diawal ya
  2. gRPC
    service ini ada pada directory /proto. dibagian ini adalah proses yang untuk menghubungkan antara Service Client dengan Service Server menggunakan gRPC. kenapa harus gRPC ?
    menurut saya pribadi gRPC lebih cocok digunakan untuk komunikasi antar service (tapi untuk komunikasi frontend seperti React/Vue/Nuxt ke service (backend) yes! you still need REST API),
    kemudian dalam hal kecepatan yang “katanya” lebih cepat dari REST karena dia menggunakan Protocol Buffer dan HTTP/2, kalian boleh baca disini untuk komparasinya
    kalian bisa update bagian ini jika ingin menambahkan parameter baru atau fungsi baru pada file/proto/*.proto kemudian generate menggunakan command berikut
    $ protoc -I proto/ proto/*.proto --go_out=plugins=grpc:proto
  3. Service Server
    service ini ada pada directory /services. dimana proses server menerima request dari gRPC yang dikirim dari Service Client disini harus dipastikan bahwa data yang dikirim harus masuk ke eventstore agar kita bisa memberi response ke user apakah proses ini gagal atau berhasil
    *Notes: point dari Eventsourcing adalah user tidak menunggu sampai semua proses selesai tapi hanya memastikan proses itu sudah masuk (ke eventstore), untuk berhasil atau tidaknya request user kita akan notif mereka menggunakan service semacam push notif (tapi tidak ada di tutorial ini yah hehe)
  4. Eventstore
    bagian ini ada dalam directory /services. dan memanggil function ke /database/eventstore. ketika Service Server menerima request maka system perlu insert ke eventstore, eventstore disini adalah data-data yang dikirim dari client kemudian kita simpan ke database, kenapa perlu disimpan ?
    jika terjadi kegagalan sistem pada proses maka data request tidak hilang dan kita bisa proses ulang (merekonstruksi) sesuai dengan event yang gagal berdasarkan aggregate_idnya
    jadi Eventstore ini bisa dikatakan sebagai checkpoint pada sistem
    *Remember: lost your data mean lost your money
    *Notes: rekomendasinya untuk eventstore ini disimpan ke NoSql ya agar lebih cepat proses insertnya, hanya saja ditutorial ini saya simpan ke database agar lebih mudah dibacanya
  5. Publish Event
    service ini ada pada directory /nats. dibagian ini dimana request dari client dipublish menggunakan NATS Streaming semua service yang listen ke masing2 channel akan tertriger untuk melakukan processnya
  6. Deposit Create & Deposit Approve
    service ini ada pada directory /deposit-create dan /deposit-approve. diservice ini kita melisten ke channel deposit-created dan deposit-approve sesuai channelnya maka kita akan meng-create atau meng-approve deposit dari client, disini kita perlu menginclude agregate-id dari eventstore ke data yang diinsert agar kita bisa tau event mana yang relate dengan data tersebut melalui agregate-id. dan ketika kita melakukan update atau delete, kita perlu insert agregate-id yang sama ke eventstore.
    khusus untuk Deposit Approve kalian bisa membuat service baru misal Service Admin yang terhubung ke gRPC untuk handle deposit-approve dari sisi admin. tapi dalam tutorial ini saya gabungkan ke Service Client agar lebih simple
  7. LOG
    service ini ada pada directory /log. ketika publish event ke channel tertentu pastikan kalian publish juga ke channel Log untuk mentrace jalannya system kalian
  8. Elasticsearch
    bagian ini ada dalam directory /database/command.go. ketika deposit created/approve maka kalian harus update ke 2 object data yang pertama ke elasticsearch dan yang kedua ke Database aslinya, well disinilah point dari CQRS ini, kenapa harus update ke 2 object ?
    ketika kalian write maka proses itu mungkin butuh waktu untuk write ke db (delay), dan kalian tidak bisa hanya memanfaatkan db replica karena inipun ada delay
    mungkin tidak terasa jika kita write hanya puluhan atau ratusan data, tapi bagaimana jika jutaan data mungkin jeda ini akan ada dan tentunya kita tidak bisa langsung membaca data tersebut
    kita perlu 1 object lagi yang cepat disini saya memilih elasticsearch.
    kalian bisa baca disini untuk benchmarknya

Notes: khusus untuk request Read dari Service Server kita langsung baca ke Elasticsearch tanpa melalui event

Oke mungkin sampai sini dulu sharingnya untuk tutorial kali ini
semoga bisa bermanfaat

jika kalian suka silakan di clap dan share artikel ini

Terimakasih

--

--

Aris Haryanto
Aris Haryanto

Written by Aris Haryanto

Cybersecurity and Software Architect

No responses yet