编程锦囊妙计——快速创建本地Mock服务

点击上方👆蓝色“Agilean”,发现更多精彩。
前情提要
在本系列上一篇文章《全文干货:打破前后端数据传递鸿沟,高效联调秘笈》中我们分享了使用Zod这一运行时类型校验库来对后端服务响应结果进行验证达到增加项目质量的方式。
这次,我们将继续分享利用这一种方式所附加的另一项能力:Mock服务。
什么是Mock服务?
mock服务是一种模拟或虚拟的服务器,用于模拟真实的API行为和响应,而无需实际访问后端服务器。这个概念在前后端项目分离,特别是开发人员分离的情况下经常被使用,有助于前后端并行开发,减少阻塞时间,提升交付时效。
常见的做法包括但不限于以下两种:
1.手动创建一份静态的响应数据声明成常量或是文件,再由程序读取;
2.资源丰富的团队可能还会自己架设一台真实服务器来提供mock服务,这类mock服务的响应结果通常会根据一定的规格文件产出随机的数据。
以上这两种方式,笔者认为均有各自的不足之处:
针对第一种,静态数据的方式体现不出数据的动态与完整性。举个例子,一份静态数据可能无法体现出某一个枚举字段的多值情况,也可能没有写出没有返回的可能字段。
针对第二种,架设公共mock服务有成本问题,以及对数据规格的描述可能会存在三方(前端、后端、mock服务)同步的问题。
综合考虑了不同应用形式的优劣势,知微前端团队开辟了另一条路:集成在前端项目中的 mock API。弥补了静态数据的不足,并且成本很小,能够尽量减少数据规格多方同步的问题。

应用逻辑:利用Schema产出Mock数据
在TypeScript中,我们可以使用 type 定义一个数据的规格,即这份数据包含了什么东西、长什么样子,为了便于大家阅读,下文统一将此称作 Schema 。
由于 TypeScript 在运行时均被擦除,以至于我们在运行时无法得到这些信息。所以在之前的分享文章中我们使用了Zod这一个库进行了 Schema 定义,它的核心作用是,将类型信息保留到了运行时,parser 也是建立在这一核心作用之上的。
关于 Zod 的作用及用法,文本不再赘述,这次带给大家的是同一赛道的另一个选手 @effect/schema。
@effect/schema 相较于 Zod 的不同点有以下几处:
更贴近函数式的编程风格。与 Zod 的 class 实现有着较大的差异,具体使用时,@effect/schema 对于类型的组合使用上会更贴近 TypeScript。使用 Zod 时,有时会因为「某个组合子的组成类型要求是某个类型的子类」而无法组合,比如 discriminatedUnion,只能组合 ZodObject 而不能是其他的复合的 ZodEffect 。
更纯粹的抽象定义。Zod 的主要目的更多的是 schema validation ,而 @effect/schema 则可以看作只是类型的一个 AST,只专注于“描述”,因此基于它可以有更多的应用可能性。
内置的 fast-check 支持。这原本是一个基于 Property 的测试框架。利用它可以产出随机数据。
当我们已经使用Schema时,实际上就可以在运行时获得我们的数据类型定义,因此可以通过编码的手段,产出对应类型的随机数据。这里我们直接借助 fast-check 的能力,来实现这点。
举个例子:


5个步骤,手把手带你实现
首先在项目中安装必要的依赖:

和之前一样,我们将 tsconfig.json 调配至合适的选项:

对请求库 wretch 进行封装。这是一个和 axios 一样用于处理网络请求的第三方库。我们对项目内的所有API请求构造器都要求传入一个 Schema 来达到 parse 和 genMockData 的作用。

上述代码通过 parser 已经达到了对接口响应结果进行类型校验的效果,这个做法思路和上一篇文章并无二致。本次的重点在于 mockFetch 的部分。这部分的代码如下:

可以看到核心是劫持了 fetch 的使用,然后用 fast-check 和 @effect/schema/Arbitrary 对Schema进行了一个mock数据的产出并结合授权状态进行返回处理。
在API构造器中具体使用时,示例如下:

当程序代码调用 rowDataCount("my-table") 时将会有两种情况:
有后端联调环境时,程序将会验证GET /model-mappings/legacy-dl/table/my-table/row-count 的返回值是否为 number
以 mock 环境启动时,程序将不发生真实的网络请求,而是会随机生成一个 number 返回给调用处
至此,通过 Schema 获得 mock 服务能力的代码,已经完整呈上。
总结
Mock服务有助于前后端分离形式的项目前后端并行开发,减少阻塞时间。在需求确认完正式编码之前,先约定协商好接口所用Schema,便可以按照约定各自编码实现。前端同学也不会因为只定义了类型而进行“盲写”并且无法启动真实的UI组件渲染。
这个方案在使用了API + 运行时类型校验器 的前提下,几乎是“免费”获得的能力。虽然本文实操是使用了「wretch+ @effect/schema」的第三方库,但是相同的逻辑下 「Axios+ Zod」依然可以达到类似的效果,Zod的生态下也有Mocking能力的实现。有兴趣的小伙伴可以就前一篇文章分享的文章,继续增强以获得相同的mock能力。
继续打开脑洞
现在后端的实现语言是Java而非TypeScript,因此定义在前端项目中的Schema和Java依然有着不同步的小问题。
而Schema本身如果只是一个AST,就意味着还可以继续写个解释器,目标是生成Java interface,作为module或者jar直接进入Java世界中对类型进行约束,团队使用TypeScript作为统一的领域通用语言,接口返回值发生变更时,只允许修改Schema来重新生成Java interface。
如此一来便可一份Schema同时约束前后两端,通过静态类型的作用,变更的影响范围将会被检查出来。
各位小伙伴,假如我填了坑,那时再见吧 👋
本文作者|林金旭
知微前端开发工程师


分享

收藏

在看

点赞
相关文章:
编程锦囊妙计——快速创建本地Mock服务
点击上方👆蓝色“Agilean”,发现更多精彩。 前情提要 在本系列上一篇文章《全文干货:打破前后端数据传递鸿沟,高效联调秘笈》中我们分享了使用Zod这一运行时类型校验库来对后端服务响应结果进行验证达到增加项目质量的方式。 这次…...
简单认识镜像底层原理详解和基于Docker file创建镜像
文章目录 一、镜像底层原理1.联合文件系统(UnionFS)2.镜像加载原理3.为什么Docker里的centos的大小才200M? 二、Dockerfile1.简介2.Dockerfile操作常用命令 三、创建Docker镜像1.基于已有镜像创建2.基于本地模板创建3.基于Dockerfile创建4.Dockerfile多阶段构建镜像 一、镜像底…...
加速乐(__jsl_clearance_s)动态cookie生成分析实战
文章目录 一、写在前面二、抓包分析三、逆向分析 一、写在前面 加速乐(JSL)是阿里推出的一项反爬虫服务,其生成cookie的原理基于浏览器的行为特征 我们知道普通网站生成cookie是在请求时生成,而它先生成cookie,然后向服…...
启动Vue项目踩坑记录
前言 在启动自己的Vue项目时,遇到一些报错,当时很懵,解决了以后豁然开朗,特写此博客记录一下。 一、<template>里多加了个div标签 [vite] Internal server error: At least one <template> or <script> is req…...
vue-pc上传优化-uni-app上传优化
vue-pc上传优化 当我们使用自己搭建的文档服务器上传图片时候,在本地没问题,上线上传会比较慢 这时候我们最简单的方法就是写一个加载组件,上传之前打开组件,掉完接口关闭组件 或者不想写直接使用element的loading写一个遮罩层加…...
【计算机视觉|生成对抗】StackGAN:使用堆叠生成对抗网络进行文本到照片逼真图像合成
本系列博文为深度学习/计算机视觉论文笔记,转载请注明出处 标题:StackGAN: Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks 链接:[1612.03242] StackGAN: Text to Photo-realistic Image Synthesis…...
跟随角色镜头时,解决地图黑线/白线缝隙的三种方案
下面一共三个解决方案,这里我推荐第二个方案解决,因为够快速和简单。 现象: 解决方案一: 参考【Unity2D】去除地图中的黑线_unity选中后有线_香菇CST的博客-CSDN博客,博主解释是因为抗锯齿采样导致的问题。 具体到这…...
redis7高级篇2 redis的BigKey的处理
一 Bigkey的处理 1.1 模拟造数 1.截图 2.代码 :使用pipe 批量插入10w的数据量 cat /root/export/monidata.txt | redis-cli -h 127.0.0.1 -a 123456 -p 6379 --pipe [rootlocalhost export]# for((i1;i<10*10;i)); do echo "set k$i v$i" >>…...
启英泰伦通话降噪方案,采用深度学习降噪算法,让通话更清晰
生活中的通话应用场景无处不在,如电话、对讲机、远程会议、在线教育等。普遍存在的问题是环境噪音、干扰声导致通话声音不清晰,语音失真等。 为了解决这一问题,启英泰伦基于自适应线性滤波联合非线性滤波的回声消除方案和基于深度学习的降噪…...
将SonarLint集成到Git
1、搭建SonarQube服务器 下载SonarQube安装包 访问SonarQube官网(https://www.sonarqube.org/downloads/)下载最新版本的SonarQube Community Edition。解压安装包 将下载的压缩包解压到一个目录,例如:D:\sonarqube-community-7.…...
【Jenkins】rpm方式安装Jenkins(2.401,jdk版本17)
目录 【Jenkins】rpm方式安装Jenkins 1、主机初始化 2、软件要求 RPM包安装的内容 配置文件说明 3、web操作 【Jenkins】rpm方式安装Jenkins 1、主机初始化 [rootlocalhost ~]# hostname jenkins[rootlocalhost ~]# bash[rootjenkins ~]# systemctl stop firewalld[roo…...
vue3跳转统一页面,path一样,传递的参数不一样时页面不刷新
vue3中当路由一样,参数quary不一样的跳转不刷新 当路由的path都是一样的,quary不一样,在跳转的时候,不会执行onMounted等方法,页面也就不会刷新。 方法: 修改router-view,在app.vue页面给标签…...
升级还是不升级?iPhone 15和iPhone 14 Plus性能比较
预览iPhone 15 Pro Max与三星Galaxy S23 Ultra之战是有正当理由的。显然,三星的旗舰智能手机为2023年的所有其他旗舰产品定下了基调——由于其超长的电池寿命和一流的摄像头,证明了它是最受欢迎的产品。 毫不奇怪,Galaxy S23 Ultra不仅是最好的照相手机之一,也是花钱能买到…...
关于LED电子显示屏幕的显示功能
因为LED显示屏的发光颜色和发光效率与制作LED的材料和工艺相关,目前广泛采用的有红、绿、蓝三种颜色的LED。这些LED的独特之处在于它们工作时需要的电压极低(仅1.5-3V),能够主动发光,并且具有一定的亮度。这亮度可以通…...
计算机视觉--利用HSV和YIQ颜色空间处理图像噪声
前言: Hello大家好,我是Dream。 今天我们将利用HSV和YIQ颜色空间处理图像噪声。在本次实验中,我们使用任意一张图片,通过RGB转HSV和YIQ的操作,加入了椒盐噪声并将其转换回RGB格式,最终实现对图像的噪声处理…...
Android Studio中引入MagicIndicator
1.github中下载文件 GitHub - hackware1993/MagicIndicator: A powerful, customizable and extensible ViewPager indicator framework. As the best alternative of ViewPagerIndicator, TabLayout and PagerSlidingTabStrip —— 强大、可定制、易扩展的 ViewPager 指示器框…...
webrtc学习(六)重要信令级时序图
一.四个重要信令 1.用户登录信令 SignIn 2..用户登出信令 SignOut 3..用户等待信令 wait信令是指从服务器的消息队列中获取暂存的中转消息,比如说sdp消息,对于信令服务器来说,他没有办法给用户推送消息,只能是用户推送消息给…...
Leetcode刷题笔记--Hot21-30
1--全排列(46) 主要思路1: 经典全排列,每次枚举每一位时,重头开始枚举,用一个访问数组记录当前已经被访问过的数字; 这道题不包含重复数字,所以不需要进行树层上的剪枝; …...
【MyBatis八股】MyBatis面试题
目录 MyBatis是什么?Mybaits的优缺点?为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?Hibernate 和 MyBatis 的区别?JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?MyBatis…...
Apache Hudi初探(二)(与flink的结合)--flink写hudi的操作(JobManager端的提交操作)
背景 在Apache Hudi初探(一)(与flink的结合)中,我们提到了Pipelines.hoodieStreamWrite 写hudi文件,这个操作真正写hudi是在Pipelines.hoodieStreamWrite方法下的transform(opName("stream_write", conf), TypeInformation.of(Object.class), operatorFa…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
macOS 终端智能代理检测
🧠 终端智能代理检测:自动判断是否需要设置代理访问 GitHub 在开发中,使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新,例如: fatal: unable to access https://github.com/ohmyzsh/oh…...
