在开发的时候,前端和后端对接的过程中,需要对接很多的接口,编写接口的mock数据,如果项目用上了TS
的话,还得为这些响应内容写ts类型,这个过程中几乎都是模板代码,很浪费时间。所以自动化这个过程的工具就提上了日程。分解一下,在部分的前端与后端对接过程中,大概是如下的几个步骤:
graph TD
接口文档输出 --> 写接口函数 --> 写ts类型 --> 写mock函数
在这个过程中,第2至4步基本上都是模板代码,写起来没啥大的变动,都是根据文档按照既定的规则写就好了。
但是按照以上步骤开发的话,会存在几个明显的问题:
- 项目中的接口数一般是几十、上百乃至更多,这么写下来会耗费我们大量的时间
- 接口发生变化的话,我们也需要同步的修改我们前端的代码
- 数据的mock类型都是基础数据,缺少根据场景来智能的mock数据
上面几点是需要解决的问题,如果说在我们的项目中可以做到下面几点:
- 自动生成接口代码
- 自动生成接口参数以及响应数据的类型代码
- 生成的代码能够自动的同步接口文档的修改
- 生成的代码可以根据项目具体场景进行二次修改
- 能够智能的mock数据
那么就可以节约前端很多的开发时间,将这个时间更多的聚焦于业务的开发,同时避免了枯燥的模板代码编写,可以极大的提升开发体验。特别是肝业务的时候,定义类型代码再想个名字,想想都头疼。
本着不重复造轮子的思想,先找了一圈开源的第三方库,最终发现pont
和apifox
结合使用可以有效的解决以上几个问题。然后就是再也不用写那些枯燥的模板代码了。由于篇幅有限,这里只是着重介绍使用频率高的功能,抛砖引玉罢了。
pont
pont是阿里开源的一个解决方案,他的官方介绍如下:
pont 在法语中是“桥”的意思,寓意着前后端之间的桥梁。 Pont 把 swagger、rap、dip 等多种接口文档平台,转换成 Pont 元数据。Pont 利用接口元数据,可以高度定制化生成前端接口层代码,接口 mock 平台和接口测试平台。
简而言之,它可以根据各种接口平台的通用数据,来生成前端的接口层代码
、ts类型
以及数据模型
。当然,这只是它的一部分特点,它还有如下的特性:
- 跨语言 天然支持 Javascript 项目及 Typescript 项目。如果使用
Java
、C++
等语言,可定制代码生成器支持 - 支持高度定制化 通过复写内部方法,各种高度定制化需求都可以满足
- VSCode 插件支持 专门为 Pont 开发的 VSCode 插件 vscode-pont,完美支持 Pont 所有能力
- 丰富的命令行提供丰富的命令行命令,满足不同场景的使用
- 自动化 mocks 服务Pont 自动生成所有 mocks 数据,并提供所有接口的 mocks 服务
我们项目的技术栈是vue3 + TS
,IDE用的是 vscode。接口文档数据是swagger
生成的,pont还有专门的vscode插件可以使用。所以pont是非常适合做这件事的。
使用
使用的话比较简单,参考pont的github文档就可以了。 按照文档安装好依赖,点击插件的按钮就可以生成代码,下面是pont生成的各部分代码:
生成的接口代码
import * as defs from '../../baseClass';
import pontFetch from 'src/utils/pontFetch';
export class Params {
/** The name that needs to be fetched. Use user1 for testing. */
username: string;
}
export const init = new defs.User();
export async function request(params) {
return pontFetch({
url: '/user/{username}',
params,
method: 'get',
});
}
生成的类型代码:
// api.d.ts
declare namespace defs {
export class Pet {
/** category */
category?: defs.Category;
/** id */
id?: number;
/** name */
name?: string;
/** photoUrls */
photoUrls?: any[];
/** pet status in the store */
status?: 'available' | 'pending' | 'sold';
/** tags */
tags?: defs.Tag[];
}
}
declare namespace API {
export namespace pet {
/**
* Find pet by ID
* /pet/{petId}
*/
export namespace getPetById {
export class Params {
/** ID of pet to return */
petId: number;
}
export type Response = defs.Pet;
export const init: Response;
export function request(params: Params): Promise<defs.Pet>;
}
}
}
业务中使用
import './services/';
// defs 包含所有公共类型
const pet = new defs.Pet();
const data = ref<API.pet.getPetById.Response>(pet);
// API 包含所有接口
API.pet.getPetById
.request({
petId: 3
})
.then(p => {
console.log(p.name);
});
可以看到,生成的代码属于生产级的,可维护性较好。使用的话,前面已经说了,按照文档来就行了,这里不再多说。这里我主要想说说使用的时候遇到的一些问题
1、使用项目自己封装的请求库:每个项目都会封装自己的请求库,用于处理一些通用的诸如token
或者是返回的业务码
之类的逻辑,那么在pont里面,是可以自定义生成的模板代码,进而使用项目自己封装的请求库。
如上图,pontcore文件只要实现fetch
和getUrl
方法就可以集成自己的请求库,或者修改生成代码模板,直接写在模板里面也可以。然后这个文件尽量放到services
文件夹之外,后面会说为啥
2、非必要不变动接口路径:pont使用的时候,会根据接口文档模型在项目的根目录下生成文件,文件结构如下:
其中mods
是用来存放生成的各种接口代码的,它的默认文件结构是跟接口的路径相关联的。
比如一个接口的路径是 /paListEval/batchSaveRules
,那么它的文件路径则如下
它的使用如下:
API.paListEval.batchSaveRules.request().then(() => {});
这里值得注意的是,如果接口已经使用的话,那么修改接口路径的话,虽说自动生成接口的地方可以重新生成,但是前端已经使用的地方就要重新手写了,这里需要跟后端协商尽量避免这种情况。
3、接口文档字段的类型尽量准确:由于pont是根据接口文档(例如swagger
)来生成类型代码的,而接口文档一般是后端来维护的。这个时候可能会遇到:
- 类型与实际类型不符合,比如本来是number类型,结果文档是string类型
- 返回的字段不是可选的,文档没有标识为必需,导致前端处理必须全部做非必要的判断处理,不然TS类型检查错误
4、接口更新:pont的可以设置每隔一段时间去检查服务器文档有没有新的变动,如果变动了则会更新本地生成的代码。这个功能使用体验不是很好,自动更新总是不能正确的更新代码。目前最佳实践是删掉整个目录,重新生成代码,也还能接受。
聊完了接口层代码生成这块儿,下面来说说mock
,mock作为前后端对接不可或缺的一环,虽然pont
也支持生成mock数据,但是跟下面的工具比起来,还是有差距的,专业的事情就交给专业的人做吧,下面来说说这个牛逼的工具
apifox
apifox是最近出来一个新的集API 文档、API 调试、API Mock、API 自动化测试于一体的工具。我选择用它的一个点主要在于它的mock
功能非常的丰富。
我在之前的项目中使用的是mockjs
来提供mock
数据,它需要对每个接口的每个属性都定义mock
规则,这个对于接口较多的项目,是一个非常痛苦的事情。而apifox
的mock功能则非常强大。它体现在以下几个方面:
1、零配置:它可以根据接口的类型来自动mock数据。换句话说,如果你对接口返回的数据不需要精细化控制的话,它直接就可以用了。不再需要定义每一个接口了
2、智能mock:智能mock
功能可以通过正则匹配的方式,匹配到一些字段,给他们应用mock规则
。apifox
有一些内置的规则,当然我们也可以自定义规则,而且,它还提供了诸如姓名
、图片
等个性化数据,这里一般配置一些常用的字段mock,比如我项目中配置的几个
3、基于数据模型:它修改mock规则是基于数据模型的。也就是它不是仅仅修改的某一个接口的mock规则,而是修改的对应的数据模型的规则。修改完成后,其他应用这个数据模型的接口也会应用到新的mock规则
,听起来好酷
4、除了接口的模型外,项目中也可以自己自定义一些模型。比如有一些字段需要返回一些数字的枚举,这个时候就可以定义一个数据模型,在任何可以使用它的地方引用这个模型就好了。
5、还有一个比较好玩的是云端mock
,这个其实就是可以和团队共享你的mock规则,或者其他人因为某种需要访问你的mock
6、高级mock:这个可以根据请求参数的不同来返回不同的mock
数据,这个功能在面对一些复杂的mock
场景时比较有用。
看了以上强大的mock
功能后,你难道不想试试吗?😃 当然,除了以上的mock
功能外,还有其他一些比较实用的功能,比如接口自动测试化
、api调试
等,可以参考官网
总结
目前呢,前后端对接大概就是上面那样了,接口代码的自动化部分由pont
来做,mock
部分就交给了apifox
,通过与之前对比,开发体验上确实提升了很多,不用再去写大量的模板代码,而且这两个工具可以在项目的任意开发周期接入。但是要想玩的更好的话,除了前端,还需要后端配合,输出一份比较标准的接口数据文档,只有这样,后续依据接口文档数据才能生成最佳实践的代码。
当然如文章所写,也还是有一些瑕疵,这就交给后面的时间了。