1. 概述

近些年来,微服务变得越来越流行。微服务基本特征是模块化、独立、易于扩展的。它们之间需要协同工作并交换数据。为了实现这一点,我们创建了名为 DTO 的共享数据传输对象。在本文中,我们将介绍在微服务之间共享DTO的方法。

2. 将域对象发布为DTO

使用微服务管理表示应用程序域的模型。域模型的关注点与 DTO 不同,我们将它们与DAO层中的数据模型分开。

这样做的主要原因是我们不想通过服务向客户暴露我们领域的复杂性。

恰恰相反,我们通过 REST API 暴露 DTO 为客户端提供服务。当DTO在这些服务之间传递时,我们将它们转换为域对象。

上面的 面向服务架构 示意性地显示了DTO到域对象的组件和流程。

3. 微服务间共享DTO

以客户订购产品的过程为例。此过程基于 Customer-Order 模型,从服务体系结构的角度来看看这个过程。

假设客户服务将请求数据发送到订单服务:

  1. "order": {
  2. "customerId": 1,
  3. "itemId": "A152"
  4. }

CustomerOrder 服务使用 contracts (契约) 进行通信。contract(或者是服务请求)以JSON格式显示。作为 Java 模型,OrderDTO 类表示客户服务和订单服务之间的契约:

  1. public class OrderDTO {
  2. private int customerId;
  3. private String itemId;
  4. // constructor, getters, setters
  5. }

3.1. 使用客户端模块共享DTO

微服务需要来自其他服务的某些信息来处理任何请求。假设有第三个微服务接收订单付款请求。与订单服务不同,此服务需要不同的客户信息:

  1. public class CustomerDTO {
  2. private String firstName;
  3. private String lastName;
  4. private String cardNumber;
  5. // constructor, getters, setters
  6. }

如果我们还添加了送货服务,客户信息将具有:

  1. public class CustomerDTO {
  2. private String firstName;
  3. private String lastName;
  4. private String homeAddress;
  5. private String contactNumber;
  6. // constructor, getters, setters
  7. }

因此,将 CustomerDTO 类放在共享模块中起不到预期的作用。为了解决这个问题,我们采用了一种不同的方法。

在每个微服务模块中,创建一个客户端模块(依赖包),并在其旁边创建一个服务端模块:

  1. order-service
  2. |__ order-client
  3. |__ order-server

order-client 模块包含一个与客户服务共享的DTO。因此,order-client模块具有以下结构:

  1. order-service
  2. └──order-client
  3. OrderClient.java
  4. OrderClientImpl.java
  5. OrderDTO.java

OrderClient 是一个接口,它定义了处理订单请求的order方法:

  1. public interface OrderClient {
  2. OrderResponse order(OrderDTO orderDTO);
  3. }

为了实现 order 方法,我们使用 RestTemplate 对象向 order 服务发送POST请求:

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

此外,order-client模块已经可以使用了。它现在成为 customer-service 模块的依赖库:

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

当然,如果 order-server 模块没有向 order-client 暴露 /create 服务端点,那也是不行滴!

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

由于这个服务端点,Customer Service 可以通过其order客户端发送订单请求。通过使用客户端模块,微服务以更加独立的方式相互通信。DTO中的属性在客户端模块中更新。因此,违背契约仅限于使用相同客户端模块的服务。

4. 结论

本文解释了一种在微服务之间共享DTO对象的方法。充其量,我们通过签订特殊契约作为微服务客户端模块(库)的一部分来实现这一点。通过这种方式,我们将服务客户端与包含API资源的服务端部分分开。这样做的好处是:

  • 服务之间没有冗余
  • 违反契约仅限于使用同一客户端的服务

    如果你觉得文章还不错,记得关注公众号: 锅外的大佬

    锅外的大佬博客

微服务之间如何共享DTO?的更多相关文章

  1. Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7867340 在前面一篇文章中,我们分析了And ...

  2. JHipster技术栈定制 - 基于UAA的微服务之间安全调用

    本文通过代码实例演示如何通过UAA实现微服务之间的安全调用. uaa: 身份认证服务,同时也作为被调用的资源服务.服务端口9999. microservice1: 调用uaa的消费者服务,服务端口80 ...

  3. spring cloud实战与思考(二) 微服务之间通过fiegn上传一组文件(上)

    需求场景: 微服务之间调用接口一次性上传多个文件. 上传文件的同时附带其他参数. 多个文件能有效的区分开,以便进行不同处理. Spring cloud的微服务之间接口调用使用Feign.原装的Feig ...

  4. spring cloud实战与思考(三) 微服务之间通过fiegn上传一组文件(下)

    需求场景: 用户调用微服务1的接口上传一组图片和对应的描述信息.微服务1处理后,再将这组图片上传给微服务2进行处理.各个微服务能区分开不同的图片进行不同处理. 上一篇博客已经讨论了在微服务之间传递一组 ...

  5. SOA和微服务之间的区别

    近几年,我们有很多文章对SOA和微服务之间的不同点和相似点进行了分析.有些人认为SOA有很多地方是值得微服务学习的,而有些人则认为区别对待微服务和SOA会更好.而Neal Ford认为,将单体迁移到面 ...

  6. SpringCloud实战 | 第五篇:SpringCloud整合OpenFeign实现微服务之间的调用

    一. 前言 微服务实战系列是基于开源微服务项目 有来商城youlai-mall 版本升级为背景来开展的,本篇则是讲述SpringCloud整合OpenFeign实现微服务之间的相互调用,有兴趣的朋友可 ...

  7. SpringBoot+SpringCloud实现登录用户信息在微服务之间的传递

    实现思路: 1:准备一个ThreadLocal变量,供线程之间共享. 2:每个微服务对所有过来的Feign调用进行过滤,然后从请求头中获取User用户信息,并存在ThreadLocal变量中. 3:每 ...

  8. 【转】SpringBoot+SpringCloud实现登录用户信息在微服务之间的传递

    实现思路: 1:准备一个ThreadLocal变量,供线程之间共享. 2:每个微服务对所有过来的Feign调用进行过滤,然后从请求头中获取User用户信息,并存在ThreadLocal变量中. 3:每 ...

  9. Restful、SOAP、RPC、SOA、微服务之间的区别

    什么是Restful Restful是一种架构设计风格,提供了设计原则和约束条件,而不是架构,而满足这些约束条件和原则的应用程序或设计就是 Restful架构或服务. 主要的设计原则: 资源与URI ...

随机推荐

  1. 电脑adb命令给智能电视安装APK

    配置环境 1.电脑需要配置好adb系统环境 具体操作较复杂,请自行百度. 2.电视打开adb命令 在电视的关于界面通过遥控器「上上下下左右左右」进入工厂模式,在「高级设置」-「其他」中的「adb开关」 ...

  2. C语言讲义——二维数组

    二维数组,又称为矩形数组 可以不太准确地理解为"数组的数组" 也可以认为是一个表格 然而内存中并不是表格存储: 二维数组的初始化 第一维度可以省略 所有元素可以写在一个花括号中,计 ...

  3. windowsAPI函数操作注册表实现软件开机自启

    注册表的结构 注册表是一个数据库,它的结构同逻辑磁盘类似.注册表包含键(Key),它类似磁盘中的目录,注册表还包含键值(Value),它类似磁盘中的文件.一个键可以包含多个子健和键值,其中键值用于存储 ...

  4. FPGA 串口

    VerilogHDL那些事儿_建模篇(黑金FPGA开发板配套教程) 作者:akuei2 说明:参照该书将部分程序验证学习一遍 学习时间:2014年5月3号 主要收获: 1. 对串口有初步了解: 2. ...

  5. rest-framework 解析器

    一 解析器的作用: 根据请求头 content-type 选择对应的解析器对请求体内容进行处理. 有application/json,x-www-form-urlencoded,form-data等格 ...

  6. 谈谈 rm -rf * 后的几点体会(年轻人得讲码德)

    事情始末 平时经常开玩笑,删库跑路.删库跑路,今天我真的rm -rf *了.早上来,一个同事说要查日志,但是日志我又备份到云磁盘了,我就想着把那一天的日志wget下来看看,然后分析.本来是想放在/va ...

  7. day6(短信验证接口)

    1.注册容联云账号 1.1注册账号 https://www.yuntongxun.com/user/login  1.2登录即可看到开发者账号信息 1.3 添加测试账号 2.使用容联云发送代码测试 ' ...

  8. PyQt(Python+Qt)学习随笔:QLineEdit行编辑器功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QLineEdit部件是一个单行文本编辑器,支持撤消和重做. ...

  9. Python中自定义类未定义__lt__方法使用sort/sorted排序会怎么处理?

    在<第8.23节 Python中使用sort/sorted排序与"富比较"方法的关系分析>中介绍了排序方法sort和函数sorted在没有提供key参数的情况下默认调用 ...

  10. Python基础教程目录

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python部分代码样例 老猿Python重难点知识博文汇总 老猿Python博客地址 第1章 Python学习环境构建目 ...