TL; DR - Apakah boleh berbagi perpustakaan POJO antar layanan?
Secara umum, kami ingin menjaga agar pembagian antar layanan sangat terbatas jika tidak ada. Ada beberapa perdebatan apakah layanan yang membagikan data harus menyediakan pustaka klien untuk digunakan klien. Client-lib umumnya opsional untuk klien dari layanan yang akan digunakan dan dapat menggunakan API namun mereka silakan, apakah akan menggunakan client-lib, atau menggunakan bahasa alternatif dan menggunakan aspek umum dari perpustakaan dan semacamnya.
Dalam kasus saya - saya mempertimbangkan layanan yang membuat objek data. Mari kita asumsikan objek ini adalah PET. BUKAN entitas basis data, tetapi POJO yang secara implisit mewakili data yang mendasarinya. POJO ini adalah apa yang telah didefinisikan oleh API. Asumsikan: Hewan Peliharaan - Usia, Berat, Nama, Pemilik, Alamat, Spesies, dll.
Layanan 1 - PetKeeper: Ini akan menghasilkan hewan peliharaan untuk alasan apa pun dan menyimpan semua data dan harus merujuk layanan ini untuk mendapatkan hewan peliharaan, atau membuat modifikasi pada Hewan Peliharaan, katakanlah perubahan nama, atau perubahan alamat harus dilakukan melalui Panggilan API ke layanan ini.
Layanan 2 - PetAccessor: Layanan ini mengumpulkan hewan peliharaan dan melakukan pemeriksaan validasi
Layanan 3,4 - Lebih banyak panggilan layanan menengah
Layanan 5 - Inteface Pengguna
Ini sangat sewenang-wenang tetapi intinya sederhana. UI atau layanan yang menghadap pengguna ingin menghadirkan objek "PET" ini. Itu harus memanggil melalui API layanan, yang memanggil layanan, yang memanggil layanan, dll sampai mencapai layanan yang mengumpulkan informasi yang diperlukan dan memulai relay kembali. Akhirnya layanan UI memiliki objek PET untuk ditampilkan.
Ini cukup umum - tetapi dengan mentalitas absolut kami, kami menduplikasi objek PET di setiap layanan. Prinsip KERING (jangan ulangi diri Anda sendiri) hanya berlaku untuk kode DI DALAM layanan dan tidak berlaku lintas layanan tetapi intinya masih ada. Bagaimana jika kita menambahkan bidang ... kita harus memodifikasi 5 layanan POJO di masing-masing.
--OR-- Kami dapat menyediakan Pet-Objects-Library yang berisi beberapa pojo dari API dan setiap layanan dapat mengimpor / ketergantungan pada perpustakaan. Tidak ada ketergantungan pada layanan itu sendiri, tetapi hanya perpustakaan umum. Saya suka ide ini sehingga setiap layanan memiliki jenis objek yang sama dan pembaruan lebih mudah. Tapi saya khawatir tentang Objek-Tuhan.
Apa pro / kontra - apa desain terbaik? Apa yang telah Anda lakukan untuk melewatkan data antar layanan untuk meminimalkan pengulangan kelas POJO yang sama sambil tetap tidak digabungkan?
sumber
Jawaban:
Anda dapat menggunakan kembali objek
Pet
DTO yang sama di antara layanan backend (yang memproses logika bisnis yang khas), tetapi ketika sampai pada tier presentasi (User Interface), umumnya merupakan praktik yang baik untuk menggunakan FormBean (kacang yang berbeda dengan bidang yang ditambahkan untuk logika presentasi) sehingga akan ada pemisahan yang jelas antara logika presentasi dan logika bisnis .Ini diperlukan karena layanan harus dapat digunakan kembali dan satu layanan dapat diekspos / digunakan kembali oleh beberapa titik akhir yang berbeda (seperti frontend atau dapat merupakan layanan web yang berbeda, dll.) Dan masing-masing titik akhir tersebut mungkin memerlukan bidang tambahan yang akan diisi oleh Pengontrol atau lapisan masing-masing (seperti adaptor) di atas layanan.
Jika Anda menggunakan satu kacang antara tingkat bisnis dan web maka Anda erat menggabungkan logika presentasi dengan logika bisnis yang bukan praktik yang baik dan Anda akhirnya akan mengubah layanan untuk persyaratan di Frontend (seperti misalnya, format tanggal yang berbeda ditampilkan di Antarmuka Pengguna). Juga, untuk membuat proses mengisi / menyalin data melintasi kacang-kacangan (seperti DTO ke FormBean atau Viceversa), Anda dapat menggunakan perpustakaan seperti Apache
BeanUtils.copyProperties()
atau Dozer untuk menghindari kode boilerplate .sumber
PetServices
untuk menghindari duplikasi. Tapi maksud saya adalah jangan erat-erat pasangan backend dan frontend, itu saja.Jika DTO mewakili entitas bisnis yang sama di semua layanan microser hanya akan ada satu kelas, dibagi di antara layanan. (Hampir) tidak pernah benar untuk memiliki kode duplikat untuk objek yang sama.
sumber
Cara saya berencana melakukannya sekarang, adalah bahwa setiap paket layanan hanya DTO dan memasukkannya ke Nexus sebagai jar lib. Ketika layanan lain membutuhkannya, itu akan mendapatkan mereka DTO lib (s) sebagai ketergantungan dalam manve / gradle. Jika versi DTO baru dirilis pada satu layanan, itu asalkan versi lama juga didukung pada saat yang sama, jadi jangan merusak kompatibilitas, versi, dll. Jadi ini adalah area backend-to-backend. Juga untuk mencegah ketergantungan sirkular Anda lebih baik memisahkan layanan dari pengemasan dto
Sekarang lihat backend-to-frontend dan sebaliknya saya tidak setuju dengan komentar sebelumnya bahwa UI sebagai lapisan presentasi berbeda. BUKAN ITU!!! UI hanyalah microservice bagi saya yang juga mengkonsumsi dan menghasilkan acara.
Arah backend-to-frontend Apa yang saya lakukan adalah mengubah POJO (dtos) menjadi antarmuka dan paket Script menjadi NPM dan memuatnya ke Nexus juga. Proyek berbasis nodej UI kemudian mengkonsumsi dan menggunakannya. Ini adalah layanan cara untuk UI.
Arah frontend -ke-backend Untuk UI untuk melayani peristiwa lapisan, saya mengonversi antarmuka TypeScript dan mengubahnya menjadi POJO (dtos), paket sebagai jar dan unggah ke Nexus (atau beberapa repo) dalam bentuk jar untuk dikonsumsi oleh layanan backend.
Proses-proses ini mudah ditangani oleh proses CI (Travis, Gitlab CI, dll.)
Setiap komentar terhadap pendekatan ini disambut baik.
sumber