1. 概述
近些年來毒坛,微服務變得越來越流行望伦。微服務基本特征是模塊化、獨立煎殷、易于擴展的屯伞。它們之間需要協(xié)同工作并交換數(shù)據(jù)。為了實現(xiàn)這一點豪直,我們創(chuàng)建了名為 DTO
的共享數(shù)據(jù)傳輸對象劣摇。在本文中,我們將介紹在微服務之間共享DTO的方法弓乙。
2. 將域對象發(fā)布為DTO
使用微服務管理表示應用程序域的模型末融。域模型的關注點與 DTO 不同,我們將它們與DAO層中的數(shù)據(jù)模型分開暇韧。
這樣做的主要原因是我們不想通過服務向客戶暴露我們領域的復雜性勾习。
恰恰相反,我們通過 REST API 暴露 DTO 為客戶端提供服務懈玻。當DTO在這些服務之間傳遞時巧婶,我們將它們轉換為域對象。
上面的 面向服務架構
示意性地顯示了DTO到域對象的組件和流程。
3. 微服務間共享DTO
以客戶訂購產(chǎn)品的過程為例艺栈。此過程基于 Customer-Order 模型英岭,從服務體系結構的角度來看看這個過程。
假設客戶服務將請求數(shù)據(jù)發(fā)送到訂單服務:
"order": {
"customerId": 1,
"itemId": "A152"
}
Customer
和 Order
服務使用 contracts (契約)
進行通信眼滤。contract(或者是服務請求)以JSON格式顯示巴席。作為 Java
模型,OrderDTO
類表示客戶服務和訂單服務之間的契約:
public class OrderDTO {
private int customerId;
private String itemId;
// constructor, getters, setters
}
3.1. 使用客戶端模塊共享DTO
微服務需要來自其他服務的某些信息來處理任何請求诅需。假設有第三個微服務接收訂單付款請求漾唉。與訂單服務不同,此服務需要不同的客戶信息:
public class CustomerDTO {
private String firstName;
private String lastName;
private String cardNumber;
// constructor, getters, setters
}
如果我們還添加了送貨服務堰塌,客戶信息將具有:
public class CustomerDTO {
private String firstName;
private String lastName;
private String homeAddress;
private String contactNumber;
// constructor, getters, setters
}
因此赵刑,將 CustomerDTO
類放在共享模塊中起不到預期的作用。為了解決這個問題场刑,我們采用了一種不同的方法般此。
在每個微服務模塊中,創(chuàng)建一個客戶端模塊(依賴包)牵现,并在其旁邊創(chuàng)建一個服務端模塊:
order-service
|__ order-client
|__ order-server
order-client 模塊包含一個與客戶服務共享的DTO铐懊。因此,order-client模塊具有以下結構:
order-service
└──order-client
OrderClient.java
OrderClientImpl.java
OrderDTO.java
OrderClient 是一個接口瞎疼,它定義了處理訂單請求的order方法:
public interface OrderClient {
OrderResponse order(OrderDTO orderDTO);
}
為了實現(xiàn) order 方法科乎,我們使用 RestTemplate 對象向 order 服務發(fā)送POST請求:
String serviceUrl = "http://localhost:8002/order-service";
OrderResponse orderResponse = restTemplate.postForObject(serviceUrl + "/create",
request, OrderResponse.class);
此外,order-client模塊已經(jīng)可以使用了贼急。它現(xiàn)在成為 customer-service
模塊的依賴庫:
[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
當然茅茂,如果 order-server
模塊沒有向 order-client
暴露 /create
服務端點,那也是不行滴太抓!
@PostMapping("/create")
public OrderResponse createOrder(@RequestBody OrderDTO request)
由于這個服務端點空闲,Customer Service 可以通過其order客戶端發(fā)送訂單請求。通過使用客戶端模塊走敌,微服務以更加獨立的方式相互通信碴倾。DTO中的屬性在客戶端模塊中更新。因此掉丽,違背契約僅限于使用相同客戶端模塊的服務跌榔。
4. 結論
本文解釋了一種在微服務之間共享DTO對象的方法。充其量机打,我們通過簽訂特殊契約作為微服務客戶端模塊(庫)的一部分來實現(xiàn)這一點矫户。通過這種方式片迅,我們將服務客戶端與包含API資源的服務端部分分開残邀。這樣做的好處是:
- 服務之間沒有冗余
- 違反契約僅限于使用同一客戶端的服務