Berbagi objek DTO antara layanan microser

15

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?

Aerith
sumber
@DaiKaixian: Tentunya Anda tidak menyarankan agar OP pergi dengan objek Dewa, bukan? Itu secara rutin dianggap sebagai anti-pola.
Makoto
Saya setuju dengan jawaban @javaguy.
Dan saya juga ingin mengatakan, Anda dapat mempertimbangkan pola pengunjung. en.wikipedia.org/wiki/Visitor_pattern . Buat semua bidang dan setter / pengambil dalam POJO, dan bagikan di antara layanan microser. Jika Anda ingin melakukan beberapa operasi pada POJO dalam layanan microser yang berbeda, tulis beberapa VisitorClass.
Terima kasih. Keraguan saya dengan memiliki 'perpustakaan umum' ini adalah bahwa itu akan tumbuh. Dan akan ada objek di sana yang hanya layanan 1 & 3 peduli, atau 2 & 4, atau semua, atau kombinasi dari sana. Jenis paket perpustakaan DTO umum yang memiliki semua DTO apakah saya menggunakan pola vistor atau DTO POJO sederhana atau apa-tidak. Apakah ini dapat diterima untuk memasukkan semua objek ini tetapi mencoba untuk mempertahankannya sebaik mungkin? Setidaknya benda-benda disediakan untuk siapa saja yang membutuhkannya JIKA mereka ingin menggunakannya ...

Jawaban:

5

Apa desain terbaik?

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.

Apa yang telah Anda lakukan untuk melewatkan data antar layanan untuk meminimalkan pengulangan kelas POJO yang sama sambil tetap tidak digabungkan?

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 .

pengembang
sumber
Saya setuju bahwa lapisan presentasi mungkin harus membatalkan deserialisasi muatan yang masuk sebagai kacang presentasi dengan atribut yang berbeda sesuai kebutuhan. Tetapi secara umum apakah boleh menggunakan kembali objek DTO yang sama di semua layanan backend? Kami biasanya akan mencoba untuk memisahkan paket DTO ini dalam paket yang lebih kecil hanya untuk beberapa layanan yang membutuhkannya. Saya lelah memiliki beberapa junk-drawer dari paket perpustakaan DTO yang memiliki DTO untuk lebih dari 75 layanan microser yang bergantung pada semua layanan. Kecuali itu ok karena itu hanya objek DTO yang opsional di tempat pertama?
Ya, Anda jelas dapat menggunakan kembali objek DTO yang sama di semua jenis layanan backend yang sama seperti Anda PetServicesuntuk menghindari duplikasi. Tapi maksud saya adalah jangan erat-erat pasangan backend dan frontend, itu saja.
pengembang
4

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.

Jim Garrison
sumber
3
Berbagi DTO di seluruh layanan mikro adalah mimpi buruk. "Apakah versi ini sudah memiliki bidang ini? Hm mungkin?" Anda akan berakhir dengan kekacauan nyata setelah beberapa saat. Kode duplikat baik dalam hal ini.
Mejmo
1

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.

kensai
sumber