前言
好久没有更新文章了,刚好最近上手React技术栈和一些新公司项目,有些抽不出时间来,我参与的一些开源项目都停止更新了,文章我也断更很久了,了解我的人都知道,我的文章面向的是一些需要进阶或者正在进阶的一些小伙伴,我的文章虽然不一定有用,但可以给你提供一个方向。一个去思考的方向。
现在社区中大部分的思路都是拿来即用,看过有一些 面试文章
中的内容甚至有出现错误的,一些解析也是半解半惑。通过这次转技术栈( vue & react
)我明白了一些软知识带来的习惯,比如 自我思考能力
, 项目拆分能力
, 驱动学习能力
等等。
真正的进阶,在我理解来看就是打破 舒适圈
,打破壁垒,思考和探索未知,当你慢慢掌握未知,不断寻找壁垒,不断打破壁垒,那么你就是一名合格的工程师了。
为什么写API
我相信在 2020
的今天,大部分前端都是在自己的项目中,将接口作为一个独立的模块划分出来,而在 view
中,只需要进行一个异步的调用就可以捕获到 后台数据
和 异常信息
。
对于将组件单独分离出来的好处就是,我们便于管理,当后台对接口调整的时候,我们只要去对应的模块更改配置信息就好了,而不需要先找页面,在找接口请求方法。
我想应该没有还将请求信息放入在组件中一起写的了吧。QAQ
正文
那么就来说下我对一个 api
的管理吧,纯属个人总结,如果有建议可以在评论区中留言,可以进行讨论和交流。
基本思路
参考于一个 约定式
的一个形式,对于 api
目录下所有文件名中带有 **.api.js
的文件,我都默认它为一个 API的模块
,举个例子
- src
-- api
---- user.api.js
---- featrue.api.js
---- index.js
这样的话,就是一个比较良好的一个状态。不论是新入职的开发者,或者是在职开发者,都能够对于 api
有一个规范式的模式在下面。那么最终,只需要将对应模块的 API接口
规范式导出就可以了。
/// @api user.api.js
export default {
getUserAuth: 'GET /api/user/auth',
postUser: 'POST /api/user',
putUser: 'PUT /api/user/:id',
deleteUser: 'DELETE /api/user/:id',
}
生成函数
最终所有的 API规范式
都会被生成为下面类似的函数
function request () {
return network({
// ...... axios参数
})
}
如何生产?
在规范式中,导出对象属性的 key
最终会被解析成请求函数的 key
,而值进行切割,最终映射成为 url
, method
。至此,一个基本的配置参数就产生出来了,其实这个函数也非常的简单。 generateSyncRequestMethod
方法的主要目的就是将包裹的模块函数化,做一个中间模型
const generateSyncRequestMethod = module => {
const result = {};
for (const key in module) {
const [method, url] = module[key].split(' ')
result[key] = (options = {}) => {
console.log('... 函数内部体系')
}
}
return result
}
RESTful规范式
对于 RESTful
来说,依旧是采用约定式的情况来说,必须有一个前后端的交流在内的,这个交流是一个固定的过程,对于接口规范来说,从 A项目
=>
B项目
来说,这个接口规范来说是一个 Team
的基本规范,做为一个不动式的状态。因此,这个规范式的问题就需要根据团队的形式来进行的,所以这里仅供参考。根据自身团队规范做处理。
使用: GET /api/model/:id
,使用该规范式,那么你在请求方法传入的参数就需要有一定的约束的。首先,在 option
属性中,你需要传入对应在规范接口中声明的 :值
作为一个约束,两者必须相等。
其次,就是对于参数了,中所周知,我们常见的请求方式大致有两个,一个式 data
的形式,常见于 POST
PUT
,而 Get
方法,则是 params
,因此才做了一个规范式,请求参数的属性,由开发者动态灵活的设置,而不是架构来做处理。让其灵活性有一个好的舒适度,同时放开些许灵活性。
request({ id: 1, data: {} })
for (const rest in options) {
if (url.includes(`:${rest}`)) {
url = url.replace(new RegExp(`:${rest}`), options[rest]);
delete options[rest];
console.log(url, options);
}
}
return network({
url,
method,
...options,
});
优点
- 约定式引导,开发者不必在去进行重复的代码编写
- 灵活度,对于参数的设置可以和后端进行,在开发时可以进行参数传递,同步到请求配置
- 同步Mock 对于一些约定式的
Mock
接口,配置相同
缺点
- 解析接口约定,需要性能消费
- 生成接口函数,需要有性能消费
- 函数方法有约束
最终,早生产环境下接口完善后将会独立的打包成为一个
chunk
文件,进行缓存
完整的代码
时间紧迫,TypeScript就没有写了,后续有时间我会补上。
// @api index.js
import network from '@/utils/network'
const PATH = './'
const ISDEEP = false
const REG = /.api.js$/
const MODE = ' sync'
const apiFiles = require.context(PATH, ISDEEP, REG, MODE)
const generateSyncRequestMethod = module => {
const result = {};
for (const key in module) {
const [method, url] = module[key].split(' ')
result[key] = (options = {}) => {
for (const rest in options) {
if (url.includes(`:${ rest }`)) {
url = url.replace(new RegExp(`:${ rest }`), options[rest])
delete options[rest]
} else {
continue
}
}
return network({
url,
method,
...options
})
}
}
return result
}
let apiResult = {}
apiFiles.keys().forEach(element => {
apiResult = {
...generateSyncRequestMethod(apiFiles(element).default)
}
})
export default apiResult
后话
如果有好的优化方式可以在下面探讨一下,优缺点的话我也进行了一些列举,也在思考一些更加深入的东西,在合理的开销下减少开发者关注api逻辑的关注,而通过约定式对于 api
进行管理。这也是我这个九月份的第一篇文章吧,刚换工作,也在换着技术栈,慢慢的也会输出 React
相关的文章了。
鸽了太久,有一些罪恶感。慢慢的调整状态,明年的目标是6级。最近买了本数据结构的书籍来学习,饿补基础。