业务流程

上面几个章节中,我们都是在这完成一个内容,即注册相关的内容,即网关和服务将自身的信息发送给网关注册中心,网关注册中心将相关信息保存到对应的库表中。

现在,我们已经有了相关的服务和网关的配置信息,但是我们在上一届章节中梳理过,我们所做的一切都是为了得到网关可以调用服务的相关映射,即api-gateway-core中的HttpStatement,现在无论是RPC服务端的相关信息,还是网关通信的相关信息,我们已经可以通过对外的注册接口拿到了,那么现在我们要做的就是通过自定义设置的分配表gateway_distribution的信息,将api-gateway-core中的HttpStatement组合出来,并对外提供相应的接口,供api-gateway-assist拉取。即我们要做的就是为服务发现模块需要从网关注册中心拉取服务配置提供接口。这个服务配置其实就是各个RPC服务配置【系统、接口、方法】,后面我们就可以通过api-gateway-assist把这些信息拉取下来,注册到网关算力中,完成RPC映射的过程。那么本章我们就先来实现这样一个接口。如下图(图片来源于xfg)

总结一下,本章节要对网关注册中心开发一个接口,这个接口用于api-gateway-assist向注册中心拉取对应网关部分的映射信息,这个映射信息是通过gateway_distribution 表,把网关和RPC应用服务关联起来,从而知道网关算力处理那些RPC映射管理。有了设个映射关系后,就可以把对应的 application_interface、application_interface_method、application_system 三个表维护应用的配置信息关联起来了。然后聚合映射信息,相应给api-gateway-assist

业务实现

项目结构如下(DDD的项目)

聚合对象以及VO的设计

首先我们先思考下,我们返回的信息应该如何聚合,我们拉取的是映射信息,但是这个映射信息应该是怎样的。我们当初在设计库表的时候,针对映射信息做了拆分,拆分为系统,接口,方法三大块,其中一个系统对应多个接口,一个接口对应多个方法。但是其实在现实世界中一个系统是包含着多个接口,而每个接口又一定包含多个方法的,因此其实一个系统就包含了相当多的接口和方法,只是我们在逻辑上进行数据库表设计的时候,参考数据库表的设计原则将其拆分了而已(拆分的是系统的本来的信息),而现在我们要将相关的映射信息返回回去,则我们再设计VO对象和聚合对象的时候,完全可以重新按照现实可能将其聚合起来,即一个网关对应着多个系统,一个系统有多个接口,一个接口包含着多个方法(哪怕是当时拆分的库表也是按照这个设计的)。所以依照这个,聚合对象,和其中用到的VO对象就出来了,我们最终返回的肯定是算力网关针对的系统的所有信息,那么

聚合对象ApplicationSystemRichInfo.java就是直接的算力网关对应着多个系统的信息

 package com.zshunbao.gateway.center.domain.manage.model.aggregates;
 ​
 import com.zshunbao.gateway.center.domain.manage.model.vo.ApplicationSystemVO;
 ​
 import java.util.List;
 ​
 /**
  * @program: api-gateway-center
  * @ClassName ApplicationSystemRichInfo
  * @description:  网关聚合信息映射-->即每个网关对应的远程服务调用映射聚合
  * @author: zs宝
  * @create: 2025-08-22 14:29
  * @Version 1.0
  **/
 public class ApplicationSystemRichInfo {
     /** 网关ID */
     private String gatewayId;
     /** 系统列表 */
     private List<ApplicationSystemVO> applicationSystemVOList;
 ​
     public ApplicationSystemRichInfo(String gatewayId, List<ApplicationSystemVO> applicationSystemVOList) {
         this.gatewayId = gatewayId;
         this.applicationSystemVOList = applicationSystemVOList;
     }
     public ApplicationSystemRichInfo(){
 ​
     }
 ​
     public String getGatewayId() {
         return gatewayId;
     }
 ​
     public void setGatewayId(String gatewayId) {
         this.gatewayId = gatewayId;
     }
 ​
     public List<ApplicationSystemVO> getApplicationSystemVOList() {
         return applicationSystemVOList;
     }
 ​
     public void setApplicationSystemVOList(List<ApplicationSystemVO> applicationSystemVOList) {
         this.applicationSystemVOList = applicationSystemVOList;
     }
 }
 ​

然后按照我们每个系统对应着多个接口,每个接口又有多个方法的显示逻辑来看,所有本节用到的库表的VO对象为

ApplicationSystemVO.java:一个系统有多个接口

 package com.zshunbao.gateway.center.domain.manage.model.vo;
 ​
 import java.util.List;
 ​
 /**
  * @program: api-gateway-center
  * @ClassName ApplicationSystemVO
  * @description: 注册系统VO
  * @author: zs宝
  * @create: 2025-08-20 14:29
  * @Version 1.0
  **/
 public class ApplicationSystemVO {
     /** 系统标识 */
     private String systemId;
     /** 系统名称 */
     private String systemName;
     /** 系统类型;RPC、HTTP*/
     private String systemType;
     /** 注册中心;zookeeper://127.0.0.1:2181*/
     private String systemRegistry;
 ​
     private List<ApplicationInterfaceVO> interfaceList;
 ​
     public String getSystemId() {
         return systemId;
     }
 ​
     public void setSystemId(String systemId) {
         this.systemId = systemId;
     }
 ​
     public String getSystemName() {
         return systemName;
     }
 ​
     public void setSystemName(String systemName) {
         this.systemName = systemName;
     }
 ​
     public String getSystemType() {
         return systemType;
     }
 ​
     public void setSystemType(String systemType) {
         this.systemType = systemType;
     }
 ​
     public String getSystemRegistry() {
         return systemRegistry;
     }
 ​
     public void setSystemRegistry(String systemRegistry) {
         this.systemRegistry = systemRegistry;
     }
 ​
 ​
     public List<ApplicationInterfaceVO> getInterfaceList() {
         return interfaceList;
     }
 ​
     public void setInterfaceList(List<ApplicationInterfaceVO> interfaceList) {
         this.interfaceList = interfaceList;
     }
 }
 ​

ApplicationInterfaceVO.java:每个接口又有多个方法

 package com.zshunbao.gateway.center.domain.manage.model.vo;
 ​
 import java.util.List;
 ​
 /**
  * @program: api-gateway-center
  * @ClassName ApplicationInterfaceVO
  * @description: 注册接口VO
  * @author: zs宝
  * @create: 2025-08-20 14:29
  * @Version 1.0
  **/
 public class ApplicationInterfaceVO {
     /** 系统标识 */
     private String systemId;
     /** 接口标识 */
     private String interfaceId;
     /** 接口名称 */
     private String interfaceName;
     /** 接口版本 */
     private String interfaceVersion;
 ​
     private List<ApplicationInterfaceMethodVO> methodList;
 ​
     public String getSystemId() {
         return systemId;
     }
 ​
     public void setSystemId(String systemId) {
         this.systemId = systemId;
     }
 ​
     public String getInterfaceId() {
         return interfaceId;
     }
 ​
     public void setInterfaceId(String interfaceId) {
         this.interfaceId = interfaceId;
     }
 ​
     public String getInterfaceName() {
         return interfaceName;
     }
 ​
     public void setInterfaceName(String interfaceName) {
         this.interfaceName = interfaceName;
     }
 ​
     public String getInterfaceVersion() {
         return interfaceVersion;
     }
 ​
     public void setInterfaceVersion(String interfaceVersion) {
         this.interfaceVersion = interfaceVersion;
     }
 ​
     public List<ApplicationInterfaceMethodVO> getMethodList() {
         return methodList;
     }
 ​
     public void setMethodList(List<ApplicationInterfaceMethodVO> methodList) {
         this.methodList = methodList;
     }
 }
 ​

ApplicationInterfaceMethodVO.java:每个方法含有的映射信息

 package com.zshunbao.gateway.center.domain.manage.model.vo;
 ​
 /**
  * @program: api-gateway-center
  * @ClassName ApplicationInterfaceMethodVO
  * @description: 注册函数VO
  * @author: zs宝
  * @create: 2025-08-20 14:29
  * @Version 1.0
  **/
 public class ApplicationInterfaceMethodVO {
     /** 系统标识 */
     private String systemId;
     /** 接口标识 */
     private String interfaceId;
     /** 方法标识 */
     private String methodId;
     /** 方法名称 */
     private String methodName;
     /** 参数类型(RPC 限定单参数注册);new String[]{"java.lang.String"}、new String[]{"cn.bugstack.gateway.rpc.dto.XReq"} */
     private String parameterType;
     /** 网关接口 */
     private String uri;
     /** 接口类型;GET、POST、PUT、DELETE */
     private String httpCommandType;
     /** 是否鉴权;true = 1是、false = 0否 */
     private Integer auth;
 ​
     public String getSystemId() {
         return systemId;
     }
 ​
     public void setSystemId(String systemId) {
         this.systemId = systemId;
     }
 ​
     public String getInterfaceId() {
         return interfaceId;
     }
 ​
     public void setInterfaceId(String interfaceId) {
         this.interfaceId = interfaceId;
     }
 ​
     public String getMethodId() {
         return methodId;
     }
 ​
     public void setMethodId(String methodId) {
         this.methodId = methodId;
     }
 ​
     public String getMethodName() {
         return methodName;
     }
 ​
     public void setMethodName(String methodName) {
         this.methodName = methodName;
     }
 ​
     public String getParameterType() {
         return parameterType;
     }
 ​
     public void setParameterType(String parameterType) {
         this.parameterType = parameterType;
     }
 ​
     public String getUri() {
         return uri;
     }
 ​
     public void setUri(String uri) {
         this.uri = uri;
     }
 ​
     public String getHttpCommandType() {
         return httpCommandType;
     }
 ​
     public void setHttpCommandType(String httpCommandType) {
         this.httpCommandType = httpCommandType;
     }
 ​
     public Integer getAuth() {
         return auth;
     }
 ​
     public void setAuth(Integer auth) {
         this.auth = auth;
     }
 }

具体实现

现在我们来实现对外的接口,在interfaces包下

GatewayConfigManage.java

     @PostMapping(value = "queryApplicationSystemRichInfo",produces ="application/json;charset=utf-8" )
     public Result<ApplicationSystemRichInfo> queryApplicationSystemRichInfo(@RequestParam String gatewayId){
         try {
             logger.info("查询分配到网关下的待注册系统信息(系统、接口、方法) gatewayId:{}", gatewayId);
             ApplicationSystemRichInfo applicationSystemRichInfo = configManageService.queryApplicationSystemRichInfo(gatewayId);
             return new Result<>(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getInfo(), applicationSystemRichInfo);
         }catch (Exception e){
             logger.error("查询分配到网关下的待注册系统信息(系统、接口、方法)异常 gatewayId:{}",gatewayId,e);
             return new Result<>(ResponseCode.UN_ERROR.getCode(), e.getMessage(),null);
         }
     }

其在对应充血模型服务中的实现为

ConfigManageService.java

     @Override
     public ApplicationSystemRichInfo queryApplicationSystemRichInfo(String gatewayId) {
         logger.info("domain 开始查询网关对应的所有服务 gatewayId:{}",gatewayId);
         ApplicationSystemRichInfo applicationSystemRichInfo = new ApplicationSystemRichInfo();
         applicationSystemRichInfo.setGatewayId(gatewayId);
         // 1. 查询出网关ID对应的关联系统ID集合。也就是一个网关ID会被分配一些系统RPC服务注册进来,需要把这些服务查询出来。
         List<String> systemIdList = configManageRepository.queryGatewayDistributionSystemIdList(gatewayId);
         if(systemIdList==null || systemIdList.size()==0){
             return applicationSystemRichInfo;
         }
         //2、根据系统id查询出所有的对应的系统信息
         List<ApplicationSystemVO> applicationSystemVOList=configManageRepository.queryApplicationSystemList(systemIdList);
         //3、现在就根据这个系统的信息,不断的去查询对应的接口表,方法表中的信息,包装进去
         for(ApplicationSystemVO applicationSystemVO:applicationSystemVOList){
             List<ApplicationInterfaceVO> applicationInterfaceVOList =configManageRepository.queryApplicationInterfaceList(applicationSystemVO.getSystemId());
             for(ApplicationInterfaceVO applicationInterfaceVO:applicationInterfaceVOList){
                 List<ApplicationInterfaceMethodVO> applicationInterfaceMethodVOList=configManageRepository.queryApplicationInterfaceMethodList(applicationSystemVO.getSystemId(),applicationInterfaceVO.getInterfaceId());
                 applicationInterfaceVO.setMethodList(applicationInterfaceMethodVOList);
             }
             applicationSystemVO.setInterfaceList(applicationInterfaceVOList);
         }
         applicationSystemRichInfo.setApplicationSystemVOList(applicationSystemVOList);
         return applicationSystemRichInfo;
     }

其对应的在仓储层的实现为

ConfigManageRepository.java

     @Override
     public List<String> queryGatewayDistributionSystemIdList(String gatewayId) {
         return gatewayDistributionDao.queryGatewayDistributionSystemIdList(gatewayId);
     }
 ​
     @Override
     public List<ApplicationSystemVO> queryApplicationSystemList(List<String> systemIdList) {
         List<ApplicationSystem> ApplicationSystem=applicationSystemDao.queryApplicationSystemList(systemIdList);
         List<ApplicationSystemVO> applicationSystemVOList=new ArrayList<>(ApplicationSystem.size());
         for(ApplicationSystem applicationSystem:ApplicationSystem){
             ApplicationSystemVO applicationSystemVO=new ApplicationSystemVO();
             applicationSystemVO.setSystemId(applicationSystem.getSystemId());
             applicationSystemVO.setSystemName(applicationSystem.getSystemName());
             applicationSystemVO.setSystemType(applicationSystem.getSystemType());
             applicationSystemVO.setSystemRegistry(applicationSystem.getSystemRegistry());
             applicationSystemVOList.add(applicationSystemVO);
         }
         return applicationSystemVOList;
     }
 ​
     @Override
     public List<ApplicationInterfaceVO> queryApplicationInterfaceList(String systemId) {
         List<ApplicationInterface> applicationInterfaces = applicationInterfaceDao.queryApplicationInterfaceList(systemId);
         List<ApplicationInterfaceVO> applicationInterfaceVOList=new ArrayList<>(applicationInterfaces.size());
         for(ApplicationInterface applicationInterface:applicationInterfaces){
             ApplicationInterfaceVO applicationInterfaceVO=new ApplicationInterfaceVO();
             applicationInterfaceVO.setSystemId(applicationInterface.getSystemId());
             applicationInterfaceVO.setInterfaceId(applicationInterface.getInterfaceId());
             applicationInterfaceVO.setInterfaceName(applicationInterface.getInterfaceName());
             applicationInterfaceVO.setInterfaceVersion(applicationInterface.getInterfaceVersion());
             applicationInterfaceVOList.add(applicationInterfaceVO);
         }
         return applicationInterfaceVOList;
     }
 ​
     @Override
     public List<ApplicationInterfaceMethodVO> queryApplicationInterfaceMethodList(String systemId, String interfaceId) {
         ApplicationInterfaceMethod req=new ApplicationInterfaceMethod();
         req.setSystemId(systemId);
         req.setInterfaceId(interfaceId);
         List<ApplicationInterfaceMethod> applicationInterfaceMethods=applicationInterfaceMethodDao.queryApplicationInterfaceMethodList(req);
         List<ApplicationInterfaceMethodVO> applicationInterfaceMethodVOList=new ArrayList<>(applicationInterfaceMethods.size());
         for(ApplicationInterfaceMethod applicationInterfaceMethod:applicationInterfaceMethods){
             ApplicationInterfaceMethodVO applicationInterfaceMethodVO=new ApplicationInterfaceMethodVO();
             applicationInterfaceMethodVO.setSystemId(applicationInterfaceMethod.getSystemId());
             applicationInterfaceMethodVO.setInterfaceId(applicationInterfaceMethod.getInterfaceId());
             applicationInterfaceMethodVO.setMethodId(applicationInterfaceMethod.getMethodId());
             applicationInterfaceMethodVO.setMethodName(applicationInterfaceMethod.getMethodName());
             applicationInterfaceMethodVO.setParameterType(applicationInterfaceMethod.getParameterType());
             applicationInterfaceMethodVO.setUri(applicationInterfaceMethod.getUri());
             applicationInterfaceMethodVO.setHttpCommandType(applicationInterfaceMethod.getHttpCommandType());
             applicationInterfaceMethodVO.setAuth(applicationInterfaceMethod.getAuth());
             applicationInterfaceMethodVOList.add(applicationInterfaceMethodVO);
         }
         return applicationInterfaceMethodVOList;
     }

最后是涉及到的mapper中的sql

gateway_distribution.xml

 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.zshunbao.gateway.center.infrastructure.dao.IGatewayDistributionDao">
 ​
     <resultMap id="gatewayDistributionMap" type="com.zshunbao.gateway.center.infrastructure.po.GatewayDistribution">
         <id column="id" property="id"/>
         <id column="group_id" property="groupId"/>
         <id column="gateway_id" property="gatewayId"/>
         <id column="system_id" property="systemId"/>
         <id column="system_name" property="systemName"/>
         <id column="create_time" property="createTime"/>
         <id column="update_time" property="updateTime"/>
     </resultMap>
 ​
     <select id="queryGatewayDistributionSystemIdList" resultType="java.lang.String">
         SELECT system_id FROM gateway_distribution
     </select>
 ​
 </mapper>

application_system.xml

 <select id="queryApplicationSystemList" parameterType="java.util.List" resultMap="applicationSystemMap">
         SELECT id, system_id, system_name, system_type, system_registry
         FROM application_system
         WHERE system_id in
         <foreach collection="list" index="idx" item="ids" open="(" close=")" separator=",">
             #{ids}
         </foreach>
     </select>

application_interface.xml

 <select id="queryApplicationInterfaceList" parameterType="java.lang.String" resultMap="applicationInterfaceMap">
         SELECT id, system_id, interface_id, interface_name, interface_version
         FROM application_interface
         WHERE system_id = #{systemId}
     </select>

application_interface_method.xml

 <select id="queryApplicationInterfaceMethodList" parameterType="com.zshunbao.gateway.center.infrastructure.po.ApplicationInterfaceMethod" resultMap="applicationInterfaceMethodMap">
         SELECT id, system_id, interface_id, method_id, method_name, parameter_type, uri, http_command_type, auth
         FROM application_interface_method
         WHERE system_id = #{systemId} AND interface_id = #{interfaceId}
     </select>

测试

     @Test
     public void test_queryApplicationSystemRichInfo(){
         ApplicationSystemRichInfo result = configManageService.queryApplicationSystemRichInfo("api-gateway-g4");
         logger.info("测试结果:{}", JSON.toJSONString(result));
     }

运行测试后拿到的json数据,放在Google浏览器的JSON-handle插件中查看

参考资料