Cara Berbagi DTO di Seluruh Microservices

1. Ikhtisar

Layanan mikro telah menjadi populer dalam beberapa tahun terakhir. Salah satu karakteristik penting dari layanan mikro adalah bahwa layanan tersebut modular, terisolasi, dan mudah diskalakan. Layanan mikro perlu bekerja sama dan bertukar data. Untuk mencapai ini, kami membuat objek transfer data bersama yang disebut DTO.

Pada artikel ini, kami akan menyajikan cara-cara di mana DTO dibagikan di antara layanan mikro.

2. Mengekspos Objek Domain sebagai DTO

Model yang mewakili domain aplikasi dikelola menggunakan layanan mikro. Model domain adalah perhatian yang berbeda, dan kami memisahkannya dari model data di lapisan DAO.

Alasan utama untuk ini adalah kami tidak ingin mengekspos kompleksitas domain kami melalui layanan kepada klien. Alih-alih, kami mengekspos DTO di antara layanan kami yang melayani klien aplikasi melalui REST API. Sementara DTO lewat di antara layanan-layanan ini, kami mengonversinya menjadi objek domain .

Arsitektur berorientasi layanan di atas secara skematis menunjukkan komponen dan aliran DTO ke objek Domain.

3. Berbagi DTO Antar Layanan Mikro

Ambil contoh, proses seorang pelanggan memesan suatu produk. Proses ini didasarkan pada model Pesanan Pelanggan . Mari kita lihat prosesnya dari sisi arsitektur layanan.

Misalkan Layanan Pelanggan mengirimkan data permintaan ke layanan Pemesanan sebagai:

"order": { "customerId": 1, "itemId": "A152" }

Layanan Pelanggan dan Pesanan berkomunikasi satu sama lain menggunakan kontrak . Kontrak, yang merupakan permintaan layanan, ditampilkan dalam format JSON. Sebagai model Java, kelas OrderDTO mewakili kontrak antara layanan Pelanggan dan layanan Pesanan:

public class OrderDTO { private int customerId; private String itemId; // constructor, getters, setters }

3.1. Berbagi DTO Menggunakan Modul Klien (Perpustakaan)

Layanan mikro memerlukan informasi tertentu dari layanan lain untuk memproses permintaan apa pun. Misalkan ada layanan mikro ketiga yang menerima permintaan pembayaran pesanan. Berbeda dengan layanan Order, layanan ini memerlukan informasi pelanggan yang berbeda:

public class CustomerDTO { private String firstName; private String lastName; private String cardNumber; // constructor, getters, setters }

Jika kami juga menambahkan layanan pengiriman, informasi pelanggan akan memiliki:

public class CustomerDTO { private String firstName; private String lastName; private String homeAddress; private String contactNumber; // constructor, getters, setters }

Jadi, menempatkan kelas CustomerDTO dalam modul bersama tidak lagi memenuhi tujuan yang dimaksudkan. Untuk mengatasi ini, kami mendekati metode yang berbeda.

Di dalam setiap modul layanan mikro, mari buat modul klien (pustaka) dan di sampingnya modul server :

order-service |__ order-client |__ order-server

The order-klien modul berisi DTO bersama dengan layanan pelanggan. Oleh karena itu, modul klien pesanan memiliki struktur berikut:

order-service └──order-client OrderClient.java OrderClientImpl.java OrderDTO.java 

The OrderClient adalah sebuah antarmuka yang mendefinisikan urutan metode untuk memproses permintaan pesanan:

public interface OrderClient { OrderResponse order(OrderDTO orderDTO); }

Untuk mengimplementasikan metode order , kami menggunakan objek RestTemplate untuk mengirim permintaan POST ke layanan Order:

String serviceUrl = "//localhost:8002/order-service"; OrderResponse orderResponse = restTemplate.postForObject(serviceUrl + "/create", request, OrderResponse.class);

Selain itu, modul order-client siap digunakan. Sekarang menjadi pustaka dependen dari modul layanan pelanggan :

[INFO] --- maven-dependency-plugin:3.1.2:list (default-cli) @ customer-service --- [INFO] The following files have been resolved: [INFO] com.baeldung.orderservice:order-client:jar:1.0-SNAPSHOT:compile

Tentu saja, ini tidak memiliki tujuan tanpa modul server-pesanan untuk mengekspos titik akhir layanan "/ create" ke klien pesanan:

@PostMapping("/create") public OrderResponse createOrder(@RequestBody OrderDTO request)

Berkat titik akhir layanan ini, layanan Pelanggan dapat mengirimkan permintaan pesanan melalui klien pesanannya. Dengan menggunakan modul klien, layanan mikro berkomunikasi satu sama lain dengan cara yang lebih terisolasi. Atribut di DTO diperbarui dalam modul klien. Oleh karena itu, pemutusan kontrak terbatas pada layanan yang menggunakan modul klien yang sama.

4. Kesimpulan

Dalam artikel ini, kami menjelaskan cara berbagi objek DTO antar layanan mikro. Paling banter, kami mencapai ini dengan membuat kontrak khusus sebagai bagian dari modul klien layanan mikro (perpustakaan). Dengan cara ini, kami memisahkan klien layanan dari bagian server yang berisi sumber daya API. Hasilnya, ada beberapa manfaat :

  • Tidak ada redundansi dalam kode DTO antar layanan
  • Pemutusan kontrak terbatas pada layanan yang menggunakan pustaka klien yang sama

Contoh kode aplikasi Spring Boot tersedia di GitHub.