前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微服务架构 | 如何设计基础通用的数据包?

微服务架构 | 如何设计基础通用的数据包?

作者头像
码农架构
发布2022-04-13 16:56:16
7800
发布2022-04-13 16:56:16
举报
文章被收录于专栏:码农架构码农架构

导读:本文主要围绕进行数据接口传值时JSON序列化对于空值问题的处理,通过里流式查降低内存使用。总结本篇文章希望对从事相关工作的同学能够有所帮助或者启发 。

作为后端开发在进行接口调试或者与其他部门日常对接工作的时候,至于数据接口都是一一对应,但是不免很多时候在进行业务针对数据接口有赋空值现象。<key,Null>类型这种现象,但是如果这样赋值在JSON序列化的时候通常会不参与序列到导致服务层无法解析对应的值。

当A服务调用服务数据包结构如下

当 type 和 extendData 两个字段赋值为Null时候的数据包,如果AB服务分开部署(不在同一个JVM)中,那么对于B服务而言在JSON序列化以后得到的数据包如下

两个对应数据相应丢失。

对于上诉场景后端面对的频率非常高,但是此类问题如何基础底层框架一次性解决能?

一、设计基础数据包


后端数据包中除了场景的VO、DO、DTO、BO之类,先前有文章整理过,不熟悉的朋友可以翻阅文章

我这里基于基类设计,对于数据对象而言通常可分为四大部分

▐ 基础数据对象-IData
代码语言:javascript
复制
/**
 * 数据对象
 */
public interface IData {
 /**
  * 读-主键
  * 
  * @return
  */
 String getFdId();

 /**
  * 写-主键
  * 
  * @param fdId
  */
 void setFdId(String fdId);

 /**
  * 读-机制类数据
  * 
  * @return
  */
 Map<String, Object> getMechanisms();

 /**
  * 写-机制类数据
  * 
  * @param mechanisms
  */
 void setMechanisms(Map<String, Object> mechanisms);

 /**
  * 读-动态数据
  * 
  * @return
  */
 Map<String, Object> getDynamicProps();

 /**
  * 写-动态属性
  * 
  * @param dynamicProps
  */
 void setDynamicProps(Map<String, Object> dynamicProps);

 /**
  * 读-固定的扩展属性
  * 
  * @return
  */
 @JsonIgnore
 Map<String, Object> getExtendProps();
}
▐ 展示数据对象接口-IViewObject

为什么需要设计IViewObject 展示数据对象接口?

比如在使用Hibernate 时候我们将数据层分为几层数据,因此我们一下所有的数据层都需继承IData

而IViewObject就是展示数据对象和接受数据对象的暴露数据包,所以要想解决空值问题,需要再这一层设计完善

代码语言:javascript
复制
/**
 * 界面展现对象接口
 */
public interface IViewObject extends IData {
 /**
  * 读-空值字段
  * 
  * @return
  */
 public List<String> getNullValueProps();

 /**
  * 写-空值字段
  * 
  * @param props
  */
 public void setNullValueProps(List<String> props);

 /**
  * 加-空值字段
  * @param props
  */
 public void addNullValueProps(String... props);
}

VO的字段为null表示不修改Entity,若要讲Entity字段设置为null,请调用addNullValueProps

▐ 展现对象基类-AbstractVO

封装基类数据自然想到了抽象类来实现,这里将继续延续上面的思路往下

AbstractVO 实现IViewObject 方便展示层封装的拓展属性可以继续给其他层级使用。

实现代码如下:

代码语言:javascript
复制
/**
 * 展示对象基类
 */
public abstract class AbstractVO implements IViewObject {
 private String fdId;

 private transient final Map<String, Object> extendProps = new HashMap<>(16);

 private Map<String, Object> dynamicProps;

 private Map<String, Object> mechanisms;

 private List<String> nullValueProps;

 @Override
 public String getFdId() {
  return fdId;
 }

 @Override
 public void setFdId(String fdId) {
  if (fdId != null) {
   IDGenerator.validate(fdId);
  }
  this.fdId = fdId;
 }

 @Override
 public Map<String, Object> getExtendProps() {
  return extendProps;
 }

 @Override
 public Map<String, Object> getDynamicProps() {
  return dynamicProps;
 }

 @Override
 public void setDynamicProps(Map<String, Object> dynamicProps) {
  this.dynamicProps = dynamicProps;
 }

 @Override
 public Map<String, Object> getMechanisms() {
  return mechanisms;
 }

 @Override
 public void setMechanisms(Map<String, Object> mechanisms) {
  this.mechanisms = mechanisms;
 }

 @Override
 public List<String> getNullValueProps() {
  return nullValueProps;
 }

 @Override
 public void setNullValueProps(List<String> nullValueProps) {
  this.nullValueProps = nullValueProps;
 }

 @Override
 public void addNullValueProps(String... props) {
  if (nullValueProps == null) {
   nullValueProps = new ArrayList<>();
  }
  for (String prop : props) {
   nullValueProps.add(prop);
  }
 }

 @Override
 public int hashCode() {
  return new HashCodeBuilder()
    .append(getClass().getName())
    .append(getFdId()).toHashCode();
 }

 @Override
 public boolean equals(Object other) {
  if (other == null) {
   return false;
  }
  if (!(other instanceof IViewObject)) {
   return false;
  }
  if (!getFdId().equals(((IViewObject) other).getFdId())) {
   return false;
  }
  return getClass().getName()
    .equals(other.getClass().getName());
 }
}

二、业务实现引用


我们举个实际例子。下面是一个 Mapper 类:

基础数据包完善后改如何对接业务场景呢?结合下面的案例来实现场景引用,记得先前写过一篇大文件分片上传的文章以及超大文件断点续传

在定义附件基础信息对象中我们可以这样依赖

写在最后

跬步至千里,小流成江海,开发工作有大小,业务需求有缓急,但终究要落到眼下,从一砖一瓦的基石开始,从一行一列的编码开始,希望本文中能帮助到更多的研发同学。

- END -

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-03-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ▐ 基础数据对象-IData
  • ▐ 展示数据对象接口-IViewObject
  • ▐ 展现对象基类-AbstractVO
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档