Desain untuk evolusi

Desain evolusioner adalah kunci untuk inovasi berkelanjutan

Semua aplikasi yang berhasil berubah dari waktu ke waktu, baik untuk memperbaiki bug, menambahkan fitur baru, menghadirkan teknologi baru, atau membuat sistem yang ada lebih dapat diskalakan dan tangguh. Jika semua bagian dari aplikasi digabungkan dengan erat, akan sangat sulit memasukkan perubahan ke dalam sistem. Perubahan di satu bagian aplikasi dapat merusak bagian lain, atau menyebabkan perubahan kecil di seluruh basis kode.

Masalah ini tidak terbatas pada aplikasi monolitik. Aplikasi dapat diuraikan menjadi layanan, tetapi tetap menunjukkan jenis penggabungan yang erat yang membuat sistem menjadi kaku dan rapuh. Namun ketika layanan dirancang untuk berkembang, tim dapat berinovasi dan terus menghadirkan fitur baru.

Layanan mikro menjadi cara populer untuk mencapai desain evolusioner, karena layanan ini menangani banyak pertimbangan yang tercantum di sini.

Rekomendasi

Terapkan kohesi tinggi dan penggabungan longgar. Layanan bersifat kohesif jika menyediakan fungsi yang secara logis milik bersama. Layanan digabungkan secara longgar jika Anda dapat mengubah satu layanan tanpa mengubah yang lain. Kohesi tinggi umumnya berarti bahwa perubahan dalam satu fungsi akan memerlukan perubahan dalam fungsi terkait lainnya, di mana semua fungsi terkait berada dalam satu layanan. Jika Anda menemukan bahwa memperbarui layanan memerlukan pembaruan terkoordinasi ke layanan lain, hal ini mungkin pertanda bahwa layanan Anda tidak kohesif. Salah satu tujuan dari desain berbasis domain (DDD) adalah mengidentifikasi batas-batas tersebut.

Merangkum pengetahuan domain. Saat klien menggunakan layanan, tanggung jawab untuk memberlakukan aturan bisnis domain tidak boleh jatuh pada klien. Sebaliknya, layanan harus merangkum semua pengetahuan domain yang berada di bawah tanggung jawabnya. Jika tidak, setiap klien harus memberlakukan aturan bisnis, dan Anda berakhir dengan pengetahuan domain yang tersebar di berbagai bagian aplikasi.

Gunakan olahpesan asinkron. Olahpesan asinkron adalah cara untuk memisahkan produsen pesan dari konsumen. Produsen tidak bergantung pada konsumen yang menanggapi pesan atau mengambil tindakan tertentu. Dengan arsitektur pub/sub, produser mungkin tidak tahu siapa yang menggunakan pesan tersebut. Layanan baru dapat dengan mudah menggunakan pesan tanpa modifikasi pada produsen.

Jangan membuat pengetahuan domain menjadi gateway. Gateway dapat berguna dalam arsitektur layanan mikro, untuk hal-hal seperti perutean permintaan, terjemahan protokol, penyeimbangan beban, atau autentikasi. Namun, gateway harus dibatasi untuk fungsi infrastruktur semacam ini. Gateway ini seharusnya tidak menerapkan pengetahuan domain, untuk menghindari dependensi yang berat.

Ekspos antarmuka terbuka. Hindari membuat lapisan terjemahan kustom yang berada di antara layanan. Sebagai gantinya, layanan harus mengekspos API dengan kontrak API yang ditentukan dengan baik. API harus dibuat versinya, sehingga Anda dapat mengembangkan API sekaligus mempertahankan kompatibilitas mundur. Dengan begitu, Anda dapat memperbarui layanan tanpa mengoordinasikan pembaruan ke semua layanan upstream yang bergantung padanya. Layanan yang menghadap publik harus mengekspos RESTful API melalui HTTP. Layanan backend mungkin menggunakan protokol olahpesan gaya RPC karena alasan performa.

Desain dan pengujian terhadap kontrak layanan. Saat layanan mengekspos API yang ditentukan dengan baik, Anda dapat mengembangkan dan menguji API tersebut. Dengan begitu, Anda dapat mengembangkan dan menguji layanan individu tanpa memutar semua layanan dependennya. (Tentu saja, Anda tetap akan melakukan integrasi dan pengujian beban terhadap layanan nyata.)

Infrastruktur abstrak jauh dari logika domain. Jangan biarkan logika domain tercampur dengan fungsi terkait infrastruktur, seperti olahpesan atau persistensi. Jika tidak, perubahan dalam logika domain akan memerlukan pembaruan pada lapisan infrastruktur dan sebaliknya.

Pindahkanmasalah pemotongan silang ke layanan terpisah. Misalnya, jika beberapa layanan perlu mengautentikasi permintaan, Anda dapat memindahkan fungsi ini ke layanannya sendiri. Kemudian Anda dapat mengembangkan layanan autentikasi — misalnya, dengan menambahkan alur autentikasi baru — tanpa menyentuh layanan yang menggunakannya.

Sebarkan layanan secara mandiri. Saat tim DevOps dapat menyebarkan satu layanan secara independen dari layanan lain dalam aplikasi, pembaruan dapat dilakukan dengan lebih cepat dan aman. Perbaikan bug dan fitur baru dapat diluncurkan dengan irama yang lebih teratur. Rancang aplikasi dan proses rilis untuk mendukung pembaruan independen.