微服务之间如何共享DTO?
1. 概述
近些年来,微服务变得越来越流行。微服务基本特征是模块化、独立、易于扩展的。它们之间需要协同工作并交换数据。为了实现这一点,我们创建了名为 DTO 的共享数据传输对象。在本文中,我们将介绍在微服务之间共享DTO的方法。
2. 将域对象发布为DTO
使用微服务管理表示应用程序域的模型。域模型的关注点与 DTO 不同,我们将它们与DAO层中的数据模型分开。
这样做的主要原因是我们不想通过服务向客户暴露我们领域的复杂性。
恰恰相反,我们通过 REST API 暴露 DTO 为客户端提供服务。当DTO在这些服务之间传递时,我们将它们转换为域对象。

上面的 面向服务架构 示意性地显示了DTO到域对象的组件和流程。
3. 微服务间共享DTO
以客户订购产品的过程为例。此过程基于 Customer-Order 模型,从服务体系结构的角度来看看这个过程。
假设客户服务将请求数据发送到订单服务:
"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 类放在共享模块中起不到预期的作用。为了解决这个问题,我们采用了一种不同的方法。
在每个微服务模块中,创建一个客户端模块(依赖包),并在其旁边创建一个服务端模块:
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资源的服务端部分分开。这样做的好处是:
- 服务之间没有冗余
- 违反契约仅限于使用同一客户端的服务
如果你觉得文章还不错,记得关注公众号: 锅外的大佬
锅外的大佬博客
微服务之间如何共享DTO?的更多相关文章
- Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7867340 在前面一篇文章中,我们分析了And ...
- JHipster技术栈定制 - 基于UAA的微服务之间安全调用
本文通过代码实例演示如何通过UAA实现微服务之间的安全调用. uaa: 身份认证服务,同时也作为被调用的资源服务.服务端口9999. microservice1: 调用uaa的消费者服务,服务端口80 ...
- spring cloud实战与思考(二) 微服务之间通过fiegn上传一组文件(上)
需求场景: 微服务之间调用接口一次性上传多个文件. 上传文件的同时附带其他参数. 多个文件能有效的区分开,以便进行不同处理. Spring cloud的微服务之间接口调用使用Feign.原装的Feig ...
- spring cloud实战与思考(三) 微服务之间通过fiegn上传一组文件(下)
需求场景: 用户调用微服务1的接口上传一组图片和对应的描述信息.微服务1处理后,再将这组图片上传给微服务2进行处理.各个微服务能区分开不同的图片进行不同处理. 上一篇博客已经讨论了在微服务之间传递一组 ...
- SOA和微服务之间的区别
近几年,我们有很多文章对SOA和微服务之间的不同点和相似点进行了分析.有些人认为SOA有很多地方是值得微服务学习的,而有些人则认为区别对待微服务和SOA会更好.而Neal Ford认为,将单体迁移到面 ...
- SpringCloud实战 | 第五篇:SpringCloud整合OpenFeign实现微服务之间的调用
一. 前言 微服务实战系列是基于开源微服务项目 有来商城youlai-mall 版本升级为背景来开展的,本篇则是讲述SpringCloud整合OpenFeign实现微服务之间的相互调用,有兴趣的朋友可 ...
- SpringBoot+SpringCloud实现登录用户信息在微服务之间的传递
实现思路: 1:准备一个ThreadLocal变量,供线程之间共享. 2:每个微服务对所有过来的Feign调用进行过滤,然后从请求头中获取User用户信息,并存在ThreadLocal变量中. 3:每 ...
- 【转】SpringBoot+SpringCloud实现登录用户信息在微服务之间的传递
实现思路: 1:准备一个ThreadLocal变量,供线程之间共享. 2:每个微服务对所有过来的Feign调用进行过滤,然后从请求头中获取User用户信息,并存在ThreadLocal变量中. 3:每 ...
- Restful、SOAP、RPC、SOA、微服务之间的区别
什么是Restful Restful是一种架构设计风格,提供了设计原则和约束条件,而不是架构,而满足这些约束条件和原则的应用程序或设计就是 Restful架构或服务. 主要的设计原则: 资源与URI ...
随机推荐
- PowerPoint无法正常加载MathType的解决方法
MathType是一款十分便捷的数学公式编辑器,可以和很多办公软件和网站兼容使用,我们日常用的比较多的也就是Office和WPS,更具体的说是Word\Excel\PPT等等一系列办公常用软件. 不过 ...
- leetcode 108 和leetcode 109
//感想:有时候啊,对于一道题目,如果知道那个点在哪,就会非常简单,比如说这两题,将有序的数组转换为二叉搜索树, 有几个点: 1.二叉搜索树:对于某个节点,它的左节点小于它,它的右节点大于它,这是二叉 ...
- python 如何跳过异常继续执行
使用try...except...语句,类似于if...else...,可以跳过异常继续执行程序,这是Python的优势 用法如下: 1 2 3 4 5 6 try: # 可能会 ...
- Session 与 sql 会话,mysql 权限设置,mybatis 逆向工程
Session 与 Sql 会话注意点: 通过 sqlSessionFactoty 工厂建立的与sql的会话,在进行相应的插入操作后,需要进行 commit 操作才会让数据库执行插入更新操作.如何主键 ...
- Contest 1445
A \(a\) 中第 \(i\) 小的配 \(b\) 中第 \(i\) 大的. 限制相同,这样配最平均. 时间复杂度 \(O\left(tn\log n\right)\). B 最终的一百名至少是第一 ...
- Kafka入门之producer
一些重要的参数: 1.acks指定了在给producer发送响应前,leader broker必须要确保已成功写入该消息的副本数.当前acks有3个取值,0,1,和all 2.buffer.memor ...
- java12(eclipse断点调试)
选择结构switch 1.格式: switch(整型数据){ case 值A:System.out.println("");break; case 值B:System.out.pr ...
- 【Usaco 2009 Gold】JZOJ2020年9月19日提高B组T3 头晕的奶牛
[Usaco 2009 Gold]JZOJ2020年9月19日提高B组T3 头晕的奶牛 题目 Description 奶牛们发现,在农场里面赛跑是很有趣的一件事.可是她们一旦在农场里面不断地转圈,就会 ...
- PyQt(Python+Qt)学习随笔:model/view架构中的QStandardItemModel使用案例
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 1.案例说明 在应用中展示指定目录的图标文件的文件名和图标,界面就是一个简单的窗口上面放置一名为li ...
- 第12.2节 Python sys模块导览
sys模块包括一些用于系统处理的功能,常用的成员包括: sys.argv:当前执行进程的命令参数列表,不含执行程序本身的名字: sys.stdin .sys.stdout 和 stderr :分别对应 ...