这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

简介

大家好,前端小白一枚,目前接触后台管理系统比较多,经常遇到不同对象的增删改查的接口,如何对Api进行一个有比较好的管理是个问题。在学习偏函数的时候有了灵感,想到一个不错的API管理方案,并应用在项目一个模块当中,并且开发效率和维护性可读性都很不错,和大家分享一下~

当前项目的前端API管理方案

// 封装的接口
export function obj1Func1(){}
export function obj1Func2(){}
export function obj2Func3(){}
export function obj2Func4(){} // 引入方式
import { obj1Func1, obj1Func2, obj2Func3, obj2Func4 } from 'xxx' // 使用方式
const params = {...}
await obj1Func1(params)

当接口多了之后,我们管理接口(查找)是一件很麻烦且废眼睛的事,需要一直翻,注释看不过来,维护性和可读性差。

统一export方式

// 封装的接口
function obj1Func1(){}
function obj1Func2(){}
function obj2Func3(){}
function obj2Func4(){}
// 导出接口
export {
obj1Func1,//注释
obj1Func2,//注释
obj2Func3,//注释
obj2Func4,//注释
...
} // 引入方式
import { obj1Func1, obj1Func2, obj2Func3, obj2Func4 } from 'xxx' // 使用方式
const params = {...}
await obj1Func1(params)

优点

  • 面向对象,不需要每个接口函数都引入,开发时调用方便
  • 简化操作类型命名,如update -> upd,开发和维护方便

缺点

  • 当模块涉及的对象很多,则需要建立非常多的文件,当文件名复杂时,难以看懂维护难度up。
  • 当页面需要引入多个对象,需要引入一个个文件,降低开发效率。
  • 找对象需要拖拽到文件最底部

以面向模块(对象)的方式

假设当前模块下涉及到 n 个对象及对应的增删改查接口, 定义一个映射表

// api映射表
const apiMap = {
// 公共接口
common: {
commonFun1,
commonFun2,
},
//对象1
dog: {
//增删改查
add: obj1Func1
get: obj1Func2
},
//对象2
cat: {
//增删改查
upd: obj2Func3,
del: obj2Func4,
},
...
}

apiMap 对象

一级键名是模块涉及的对象
二级键名是对象相关的操作类型,值是对应的接口函数

导出方式1

直接导出各个对象

export default {
commonApi: apiMap['common'],
dogApi: apiMap['dog'],
catApi: apiMap['cat'],
} import {commonApi,...} from "xxx"

面向模块(多个对象)

本质就是以对象的方式来进行管理,只不过这里面向的是模块。这里一个模块只对应一个文件,包含了涉及到的n个对象的接口。因为我觉得一个模块下建n个对象一长串的Api文件,又没法对文件名注释(文件名总有不认识或拼接的单词吧)只会带来更大的维护困难

找了几个不常见的英语名词,英语烂仔直接带上痛苦面具

而有了映射表就相当于有了一个目录(文件最上方一目了然, Map下的对象十分清晰还有注释),

至少目前我是能都秒读懂接口含义了

也不会出现面对老项目里那种长得拖不完的不知名接口文件的懵逼,点进去还只有几行代码(雪花飘飘~)

优点:

  • 同上
  • apiMap变成接口目录,可读性和可维护性提高(下方介绍)
  • 涉及同模块多个对象只需要引入一个文件

缺点:

  • apiMap(目录)和export的位置一个在文件最上方,一个在最下方,浏览时非常不方便,依旧需要经常拖拽

这种方式已经比较好用了,从可维护性和可读性,拓展性来看我更推荐第二种方式

导出方式2

导出一个访问映射表的函数,参数是对象及操作类型,如(dog, upd)

// 暴露一个访问api映射表的函数, 参数是对象和操作
// 这里没有错误处理,jym看懂就行
export default function api(obj, action) {
if (action) {
// 返回某对象某操作的接口函数,如dogUpdate
return apiMap[obj][action]
}
// 返回一个包含多个操作接口函数的对象或公共接口
return apiMap[obj]
} // 封装的接口
function obj1Func1(){}
function obj1Func2(){}
function obj2Func3(){}
function obj2Func4(){}

使用时方式1

import API from 'xxx'
// 没有错误处理,主打看懂
async function getData() {
const params = {...}
const data = await API(obj1, 'get')(params)
await API(obj1, 'upd')(params)
await API(obj1, 'del')(params)
}
使用时方式2
import API from 'xxx'
const obj1API = API(obj1) const data = await obj1API.get(params)
const data = await obj1API.upd(params)
const data = await obj1API.del(params)

api函数

api函数可以复制或者写在公共模块引入就行了,实际上工作量只在维护映射表apiMap

现在查找接口原本一个模块里可能涉及10个对象共100个接口,顺序查找最差情况要看100条函数注释,而根据对象查找最差情况是10(对象)+10(操作类型)即20条函数注释。

const apiMap = {
...
// 注释:这是target对象
targetObj: {
add: objAddFunc, // 注释:增删改查的话可有可无
upd: objUpdateFunc,
del: objDeleteFunc,
get: objGetFunc,
}
...
}

只需要关注目标对象(其实是注释),清晰且一目了然,甚至不需要函数注释,不需要拖到文件底部

可维护性和可读性

模块化

这种方式用对象结构拆分也算是模块化了,看着不太习惯,但一个文件里对象和接口能都读懂,维护性和可读性也更好,即便接口函数再多行数再多,其实也只需要看apiMap

封装

(接下来开始胡扯~)

api函数封装了一层,可以统一管理接口提高拓展性和复用性,例如统一给actionget的套一个节流函数

// 暴露一个访问api映射表的函数, 参数是对象和操作
// 这里没有错误处理,jym看懂就行
export default function api(obj, action) {
if (action) {
if (action === "get") {
return throttle(apiMap[obj][action], 500); // 设置节流时间为 500 毫秒,期间返回空函数
}
return apiMap[obj][action]
}
// 返回一个包含多个操作接口函数的对象或公共接口
return apiMap[obj]
}

或者当模块下有多个对象需要增删改查,且只需要一个参数id,那么只要再加个定制场景的api函数

// 偏函数固定参数,这里constParams假设为 { id:007 }
export function paramsApi(constParams, obj) {
// otherParams是额外参数,在各自接口做个合并Object.assign()
return (action, otherParams) => apiMap[obj][action](otherParams)
}
// 固定参数
const constParams = { id: 007 }
const dogApi = paramsApi(constParams, 'dog')
const catApi = paramsApi(constParams, 'cat')
// 免参数直接调用即可
dogApi('get')
dogApi('update', { color: 6 })
dogApi('delete')
catApi('get')
catApi('update', { color: 6 })
catApi('delete')

这个场景有些理想化,但有一层封装也确实能够在需要时方便统一管理

然后这里 action: objActionFunc这里也算是一层封装,方便进行命名简写和规范

// xxxModule.js
const apiMap = {
//对象1
obj: {
action: objActionFunc
add: dogAdd, // xxx/dog/add
mAdd: dogImport, // xxx/dog/import
upd: dogUpdate, // xxx/dog/update
},
}

开发体验

和同事沟通后,我应用在项目的一个模块中,感觉很棒!

首先写接口引入公共模块的api函数,定义apiMap映射表,正常写接口,工作量多了一个apiMap罢了

// 引入api,getType函数
import { api } from "common"
// api映射表
const apiMap = {
...
}
// 暴露api函数
export default api
// 封装的接口
...
开发时查找接口就全程对着文件最上方的映射表复制,基本不需要怎么拖拽,不需要切换文件去找其他对象,也不需要看一堆无关代码,全程看注释,大大降低心智负担,小白上手也能分分钟找到
// xxxModule.js
const apiMap = {
//对象1
dog: {
add: xxx
get: xxx
},
//对象2
cat: {
upd: xxx,
del: xxx,
},
}
引入接口时只要一个API函数,调用方式基本大差不差吧,反正都是copy,然后改下操作类型
import API from "@/api/xxx/xxxModule"

// 调用时, 两种方式,复制个对象名,记住个操作类型,完事
const dogAPI = API('dog')
const catAPI = API('cat') await dogAPI.get(params)
await dogAPI.upd(params)
await catAPI.get(params)
// 或
await API('dog', 'get')(params)
await API('dog', 'upd')(params)
await API('cat', 'get')(params)

开发效率我觉得和对象方式的API管理方案没啥区别,都是copy然后改下操作类型,但其实最大的好处还是在可维护性和可读性上

写在最后

非常感谢看到最后的jym,这是我本0前端小白通过偏函数产生的一点小想法,感觉挺好用的分享一下(可能场景比较简单局限后台系统),欢迎jym多多指点发表建议(玻璃心

本文转载于:

https://juejin.cn/post/7290558277666930744

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--这个前端Api管理方案会更好?的更多相关文章

  1. 前端api管理工具YApi

    使用YApi接口管理工具,提升前端开发效率前端开发苦恼: 代码中使用json数据模拟后端api数据,注释调取api接口代码,代码乱七八糟 为了测试不同case,央求后端人员返回不同的数据,返回状态.返 ...

  2. Redux/Mobx/Akita/Vuex对比 - 选择更适合低代码场景的状态管理方案

    近期准备开发一个数据分析 SDK,定位是作为数据中台向外输出数据分析能力的载体,前端的功能表现类似低代码平台的各种拖拉拽.作为中台能力的载体,SDK 未来很大概率会需要支持多种视图层框架,比如Vue2 ...

  3. NPM 与前端包管理

    我们很清楚,前端资源及其依赖管理一直是 npm 的重度使用场景,同时这也一直是 Node.js 普及的重要推动力.但这类应用场景到底有多重度?这是一个很难回答的问题.这份 “npm 最常下载的包的清单 ...

  4. 2023 年十大 API 管理趋势

    本文探讨了 API 管理在数字化转型中的重要性,以及 API 管理面临的挑战和发展机遇.文章重点介绍了十大 API 管理发展趋势,包括 API 安全性.API 标准化.云端 API 管理解决方案.低代 ...

  5. 【Azure API 管理】在APIM 中添加 log-to-eventhub 策略,把 Request Body 信息全部记录在Event Hub中

    问题描述 根据文档 https://docs.azure.cn/zh-cn/api-management/api-management-howto-log-event-hubs, 可以将Azure A ...

  6. 前端API层架构,也许你做得还不够

    上午好,今天为大家分享下个人对于前端API层架构的一点经验和看法.架构设计是一条永远走不完的路,没有最好,只有更好.这个道理适用于软件设计的各个场景,前端API层的设计也不例外,如果您觉得在调用接口时 ...

  7. API管理之YApi实现前后端高度分离

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/11972789.html,多谢,=.=~ 背景描述   前后端分离已成为互联网项目开发的业界标准使 ...

  8. H5 hybrid开发-前端资源本地化方案纪要

    H5 hybrid-前端资源本地化方案纪要 就整个行业来说,大前端是趋势,现阶段,native方面除了一些偏CPU密集型工作与操作系统底层API方面的工作外,H5基本都可以满足需要. 目前的工作更偏向 ...

  9. 你必须知道的容器日志 (2) 开源日志管理方案 ELK

    本篇已加入<.NET Core on K8S学习实践系列文章索引>,可以点击查看更多容器化技术相关系列文章.上一篇<你必须知道的容器日志(1)>中介绍了Docker自带的log ...

  10. 循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理

    在前面随笔<循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理>介绍了一个系统最初接触到的前端登录处理的实现,但往往对整个系统来说,一般会有很多业务对 ...

随机推荐

  1. python绘图总结

    1 二维图像 1.1 二维曲线 plot(x, y, ls="-", lw=1.5, label=None) x, y:横坐标和纵坐标 ls:颜色.点标记.线型列表,如 ls='r ...

  2. MySQL日志:slow query log

    ySQL的慢查询日志可以用来找出执行时间过长的查询语句,并进行针对性的优化.   一.slow log相关参数 以下参数都是动态参数,可以在实例运行时修改. slow_query_log=1 #是否启 ...

  3. BUU PWN RIP1 RET2CODE WRITEUP

    1.下载附件后,运行是一个输入程序,IDA分析main函数,gets可溢出. F5伪代码如下: int __cdecl main(int argc, const char **argv, const ...

  4. 【Android 逆向】r0zapataNative.apk 破解

    1. apk 安装到手机,需要输入内容,随便输入,提示fail... 2. apk 导入到jadx中查看一下 MainActivity.java String textData = "b2F ...

  5. Java缓存框架整理

    Spring Cache 为基于Spring框架的应用提供了一套完整的缓存API抽象,具体的缓存实现可以对接如Ehcache,Redis等. https://docs.spring.io/spring ...

  6. django中的Case,When,then用法

    # 参考文档 https://docs.djangoproject.com/en/2.2/ref/models/conditional-expressions/ # Case()接受任意数量的When ...

  7. python实用模块之netifaces获取网络接口地址相关信息

    文档 https://pypi.org/project/netifaces/ 安装 pip install netifaces 使用 import netifaces netifaces.interf ...

  8. 2.Go 的指针

    Go的指针 1. 变量内存地址 var age = 18 // & + 变量 = 变量内存地址 fmt.Println("age:",&age) 2. 指针变量 / ...

  9. 解析Spring中的循环依赖问题:再探三级缓存(AOP)

    前言 在之前的内容中,我们简要探讨了循环依赖,并指出仅通过引入二级缓存即可解决此问题.然而,你可能会好奇为何在Spring框架中还需要引入三级缓存singletonFactories.在前述总结中,我 ...

  10. 【Azure Redis 缓存】Azure Redis Cluster 在增加分片数时失败分析

    问题描述 Azure Redis Cluster 在增加分片数时失败,错误消息为: ResponseBody: { "error": { "details": ...