上午好,今天为大家分享下个人对于前端API
层架构的一点经验和看法。架构设计是一条永远走不完的路,没有最好,只有更好。这个道理适用于软件设计的各个场景,前端API
层的设计也不例外,如果您觉得在调用接口时还存在诸多槽点,那就说明您的接口层架构还待优化。今天我以vue + axios
为例,为大家梳理下我的一些经历和设想。
石器时代,痛苦
直接调用axios
,真的痛苦,每个调用的地方都要进行响应状态的判断,冗余代码超级多。
import axios from "axios"
axios.get('/usercenter/user/page?pageNo=1&pageSize=10').then(res => {
const data = res.data
// 判断请求状态,success字段为true代表成功,视前后端约束而定
if (data.success) {
// 结果成功后的业务代码
} else {
// 结果失败后的业务代码
}
})
复制代码
看起来确实很难受,每调用一次接口,就有这么多重复的工作!
青铜器时代,中规中矩
为了解决直接调用axios
的痛点,我们一般会利用Promise
对axios
二次封装,对接口响应状态进行集中判断,对外暴露get
, post
, put
, delete
等http
方法。
axios二次封装
import axios from "axios"
import router from "@/router"
import { BASE_URL } from "@/router/base-url"
import { errorMsg } from "@/utils/msg";
import { stringify } from "@/utils/helper";
// 创建axios实例
const v3api = axios.create({
baseURL: process.env.BASE_API,
timeout: 10000
});
// axios实例默认配置
v3api.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded';
v3api.defaults.transformRequest = data => {
return stringify(data)
}
// 返回状态拦截,进行状态的集中判断
v3api.interceptors.response.use(
response => {
const res = response.data;
if (res.success) {
return Promise.resolve(res)
} else {
// 内部错误码处理
if (res.code === 1401) {
errorMsg(res.message || '登录已过期,请重新登录!')
router.replace({ path: `${BASE_URL}/login` })
} else {
// 默认的错误提示
errorMsg(res.message || '网络异常,请稍后重试!')
}
return Promise.reject(res);
}
},
error => {
if (/timeout\sof\s\d+ms\sexceeded/.test(error.message)) {
// 超时
errorMsg('网络出了点问题,请稍后重试!')
}
if (error.response) {
// http状态码判断
switch (error.response.status) {
// http status handler
case 404:
errorMsg('请求的资源不存在!')
break
case 500:
errorMsg('内部错误,请稍后重试!')
break
case 503:
errorMsg('服务器正在维护,请稍等!')