首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >发明专利公开 -- 一种基于 JSON 文件 + Http Header 的支持多项目、多分支、多人协同的 Api Mock/代理 工具

发明专利公开 -- 一种基于 JSON 文件 + Http Header 的支持多项目、多分支、多人协同的 Api Mock/代理 工具

作者头像
奋飛
发布2023-05-31 14:37:14
2220
发布2023-05-31 14:37:14
举报
文章被收录于专栏:Super 前端Super 前端

现阶段主流的前后端分离的开发模式下:前后端采用并行开发方式,在前端开发过程中通常需要依附于共同约定的接口格式及数据。

在这里插入图片描述
在这里插入图片描述

该过程是一个并行过程,因此 Api Mock 模拟接口的返回变成了必要。同时,联调过程中,修改后端服务地址进行联调也是必要的。

现公布团队的解决方案,也是团队 21 年专利的一项内容(专利公布号:CN113630468A)。

历史现状

前端开发时本地需要启动两个服务,一个服务用于支撑 web 静态资源,一个用于模拟后台 API 接口。

其中静态资源服务包含一个代理 API 地址功能,该代理功能用于将浏览器发送来的后台数据接口(一般接口前缀都具有相同的特征,比如都以 “api/” 开头)进行转发,转发到后台 API 接口的服务上。那么大概有以下 3 个使用场景:

  1. 在开发前端页面时,会将代理设置到本地模拟后台 API 接口的服务上(如下图中的开发环境地址:http://localhost:8080)
  2. 在和后台接口联调时,会将代理设置到后台 API 接口服务(如下图中的后台环境地址:http://192.168.0.100:8080)
  3. 在测试阶段,前端排查问题是可能会将代理设置到测试环境的 API 接口服务(如下图中的测试环境地址:http://192.168.0.200:8080)
在这里插入图片描述
在这里插入图片描述

带来的问题:

  1. 联调的时候可能是一对多(一位前端开发者与多个后台开发者进行联调),多个后台开发者意味有多个后台环境的地址。那么与“后台 A”联调完成后,需要将代理切换到“后台 B”,如此轮换,也有可能与 “后台 A”、“后台 B”交叉联调。而这种方式在当前的前端项目机制中,更改代理地址的步骤: 第一步:修改配置文件中的 ip 地址 第二步:杀掉前端服务 第三步:重新启动前端服务(此过程会执行前端静态资源的编译过程,根据项目大小不同启动速度不同) 总之为了改一下代理地址需要额外做很多不相干的事情,影响开发与联调的效率。
  2. 一位前端开发者往往会穿插在多个前端项目中。比如以下场景:
在这里插入图片描述
在这里插入图片描述

多个项目并行,这中间可能造成代理地址端口冲突的问题,这同样需要频繁的修改代理地址,然后重新启动前端项目

实现思路

实现目标:修改代理地址,无需重新编译前端整个工程! 实现方式:抽离统一的代理服务 fusion-mock,前端项目工程中代理地址统一为 fusion-mock 的地址;在 fusion-mock 中进行目标地址的转发策略配置!

在这里插入图片描述
在这里插入图片描述

开发一个统一的代理平台,所有项目代理目标地址为该平台。平台中通过识别相应标识,来确定不同项目、不同开发者,然后按照获取到的信息进行转发处理,从而实现无需每次修改目标地址(避免重复构建),统一管理。

在这里插入图片描述
在这里插入图片描述

Mock 数据存储方式由「DB」改进为「JSON文件」 使用 JSON 文件存储(每一个接口对应一个 JSON 文件),无需搭建独立 DB 服务。相关 JSON 文件管理简单,可跟随项目一同托管到 Git 等相关代码仓库中。

  • 创建简单:如:/api/users/person/jerry => 在 /users/person 目录下创建 jerry.json 即可,关系清晰易懂!
  • 方便管理:Mock 数据存储到当前项目工程中,作为资源文件同项目源码进行统一管理。配合开发流程,Mock 数据可以很好的隔离和复用。
  • 无需部署:不需要独立的 Mock 服务(包括 DB 服务等)
在这里插入图片描述
在这里插入图片描述

通过 Http Header 标识相关信息,统一代理地址

const mockPath = join(__dirname, 'mock')

devServer: {
  host: '0.0.0.0',
  proxy: {
    '/api': {
      // fusion-mock地址
      target: 'http://localhost:18080',
      /*
      * 'mock-server': '项目标识',
      * 'mock-path':'mockdata路径'
      */
      headers: { 'mock-server': 'am-fe', 'mock-path': mockPath },
      changeOrigin: true
    },
    '^/websocket': {
      target: 'ws://localhost:18080',
      headers: { 'mock-server': 'am-fe' },
      changeOrigin: true,
      ws: true
    }
  }
}

所有开发者可统一配置成 Fusion Mock 的服务地址(如:httsp://domain:port);不同项目通过 headers 中的字段进行关联。切换连接地址无需重新构建,只需在工具上动态修改即可。

在这里插入图片描述
在这里插入图片描述

同一项目,多人协同模式 对于同一项目在线协同开发,多个开发者需要连接不同目标服务器,可以识别 Http Referer 来标识不同开发者,进行差异转发。 ​Referer: http://localhost:8080/api/auth/time?xxx

在这里插入图片描述
在这里插入图片描述

具体实施

在这里插入图片描述
在这里插入图片描述

mock 机制,需要先在项目目录下实现与 API 路径、存储 JSON 文件路径相匹配的机制。API 路径中最后一层为 JSON 文件名称,前面的则为文件夹目录。比如:/users/person/jerry 则对应的 JSON 文件文件为:项目路径 /mocks/users/person/jerry.json

mocks/server.js

app.use(async ctx => {
  let url = ctx.request.url
  // /api/users/person/jerry => /mocks/users/person/jerry.json
  let filePath = path.join(__dirname, ctx.request.path.replace('/api/', '') + '.json')
  let data
  if (fs.existsSync(filePath)) {
    try {
      data = jsonfile.readFileSync(filePath)
    } catch (err) {
      console.error('request: ' + url + ' fail!!!')
    }
  } else {
    console.warn('request: ' + url + ' not exist!!!!')
  }
  ctx.set('Content-Type', 'application/json')
  ctx.body = data
})

实现一款集成化代理的工具,前端所有项目都将请求转发到此工具地址,统一由此工具进行分配(根据设置好的地址进行二次转发)。详细说明如下:

前端在 Header 中体现出自己的标识(在 Header 中体现对项目没有侵入性)

proxy: {
	'/api': {
  	// fusion-mock地址
		target: 'http://localhost:18080',
 		/*
  	 * 'mock-server': '项目标识',
  	 * 'mock-path':'mockdata路径'
  	 */
  	headers: { 'mock-server': 'am-fe', 'mock-path': path.join(__dirname, 'mock') },
		changeOrigin: true
  }
}

集成化代理工具识别 Header 中的身份标识,并根据身份标识进行相关的代理设置与读取

集成化代理工具可以根据 referer 中的关键字进行匹配代理转发

集成化代理工具在读取到该项目没有设置代理时,默认使用 header 中携带的绝对 mock 路径进行读取该项目中的 JSON 文件。

 // mockServer 应该是被代理项目的名称,也是mock-assets中的文件夹名称
 const mockServer = ctx.header['mock-server'] as string
 const mockPath = ctx.header['mock-path'] as string
 
 // 如果匹配到了 referer 的配置或者开启了 proxy
 if (isMatcheMReferer || isttpRemoteProxy) {
   // 转发到目标 url
   await await proxyBranch(ctx, targetUrl)
   // return 结束函数运行
   return
 }
 
 // 拆解path路径 找到对应的文件,ctx.mockpath 为 mock 地址的绝对路径
 const filePath = join(_mockPath, ctx.path.replace(searchValue, '') + '.json')
 // read. 读取文件内容
 const content = await promises.readFile(filePath, 'utf8')
 ctx.body = JSON.parse(content)
 ```

总结

  1. JSON 文件路径与 API 路径匹配的存储形式(简单高效);
  2. 依赖 Http Header 识别身份,进行动态代理;
  3. 依赖 Http Referer 定制化代理实现的多人协同模式。

如何将“变量”抽离是解决上述问题的核心,然后借助传输过程传递“变量”,统一逻辑处理。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-05-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 历史现状
  • 实现思路
  • 具体实施
  • 总结
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档