微服務之間如何共享DTO?

1. 概述

近些年來,微服務變得愈來愈流行。微服務基本特徵是模塊化、獨立、易於擴展的。它們之間須要協同工做並交換數據。爲了實現這一點,咱們建立了名爲 DTO 的共享數據傳輸對象。在本文中,咱們將介紹在微服務之間共享DTO的方法。javascript

2. 將域對象發佈爲DTO

使用微服務管理表示應用程序域的模型。域模型的關注點與 DTO 不一樣,咱們將它們與DAO層中的數據模型分開。
這樣作的主要緣由是咱們不想經過服務向客戶暴露咱們領域的複雜性。java

偏偏相反,咱們經過 REST API 暴露 DTO 爲客戶端提供服務。當DTO在這些服務之間傳遞時,咱們將它們轉換爲域對象。shell

dto

上面的 面向服務架構 示意性地顯示了DTO到域對象的組件和流程。架構

3. 微服務間共享DTO

以客戶訂購產品的過程爲例。此過程基於 Customer-Order 模型,從服務體系結構的角度來看看這個過程。
假設客戶服務將請求數據發送到訂單服務:app

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

CustomerOrder 服務使用 contracts (契約) 進行通訊。contract(或者是服務請求)以JSON格式顯示。做爲 Java 模型,OrderDTO 類表示客戶服務和訂單服務之間的契約:maven

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 類放在共享模塊中起不到預期的做用。爲了解決這個問題,咱們採用了一種不一樣的方法。post

在每一個微服務模塊中,建立一個客戶端模塊(依賴包),並在其旁邊建立一個服務端模塊:3d

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);
}

爲了實現 order 方法,咱們使用 RestTemplate 對象向 order 服務發送POST請求:

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

此外,order-client模塊已經可使用了。它如今成爲 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客戶端發送訂單請求。經過使用客戶端模塊,微服務以更加獨立的方式相互通訊。DTO中的屬性在客戶端模塊中更新。所以,違背契約僅限於使用相同客戶端模塊的服務。

4. 結論

本文解釋了一種在微服務之間共享DTO對象的方法。充其量,咱們經過簽定特殊契約做爲微服務客戶端模塊(庫)的一部分來實現這一點。經過這種方式,咱們將服務客戶端與包含API資源的服務端部分分開。這樣作的好處是:

  • 服務之間沒有冗餘
  • 違反契約僅限於使用同一客戶端的服務
    若是你以爲文章還不錯,記得關注公衆號: 鍋外的大佬
    鍋外的大佬博客
相關文章
相關標籤/搜索