接口按功能分类
一个项目中肯定存在多个不同的功能,各个功能会有对应的接口,为了更方便管理,对项目的接口进行分类导出,后续需要对对应功能模块的接口进行修改或者查找会比较方便
声明一个metaData功能的接口文件,将属于该功能下的接口都放到一起,然后抛出
// service/mapping/metaApi
const metaApi = {
'meta-api':{
url:`${service}/meta/index`,
type:'get'
},
'meta-api-detail':{
url:`${service}/meta/detail`,
type:'get'
},
'meta-api-create':{
url:`${service}/meta/create`,
type:'post'
}
}
export default metaApi
整合统一各个功能接口
上面只是一个接口模块,接着需要对接口模块进行统一整合,放到一个index文件中,将所有的接口抛出,而不是用到哪个功能引入哪个模块接口。
//service/mapping/index
import metaApi from './metaAapi' //引入接口模块
import sourceAapi from './sourceAapi'
import textAapi from './textAapi'
//引入的模块都是一个个对象,进行解构,统一放到一个全局接口中
const apiMapper = {
...metaApi
...sourceAapi
...textAapi
}
exprot default apiMapper
解析出来可以看到apiMapper的具体样子
对上面的apiMapper的type处理
apiMapper的type主要是对接口的一个类型的备注,虽然都是get类型,但是可能传送参数的配置不同,所以先进行备注,接着通过serviceType文件来对备注进行归类,设置备注对应的请求方式。
//serviceType.js
const get = {
"get-body":'GET',
"get-quert":'GET',
"get":'GET',
}
const post = {
"post-body":'POST',
"post-quert":'POST',
"post":'GET',
}
const del = {
'delete': 'DELETE',
'delete-body': 'DELETE'
};
export default {
...get,
...post,
...del,
}
按接口类型进行配置
设置一个getconfig函数,进行config配置的设置,传入的是上方接口的类型备注,按照不同的类型设置各类类型的请求头,比如get和getbody虽然都是method都是get,但是config内容不同,get需要对参数进行序列化
这里我们引入qs插件对参数进行序列化,paramsSerializer不同的配置参数的序列化格式不同
data:{
areaID:'11',
area:'11',
apiKey:'11',
dayList:[1,2,3,4]
},
paramsSerializer: (data) => qs.stringify(data, { indices: false }),
import typeMap from "./serviceType";
export function getConfig(type,body=undefined,query=undefined){
let conf = {};
switch(type){
case 'get':
conf = {
params: query,
paramsSerializer(params) {
return qs.stringify(params, {
arrayFormat: 'repeat'
})
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
responseType: 'json'
}
break;
case 'get-body':
conf = {
params: query,
headers: {
'Content-Type': 'application/json'
},
responseType: 'json'
};
break;
case 'postJSON':
conf = {
data: data,
headers: {
'Content-Type': 'application/json',
}
}
break;
case 'download-param':
conf = {
params: data,
paramsSerializer(params) {
return qs.stringify(params, { arrayFormat: 'repeat' })
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
responseType: 'blob'
}
break;
}
conf.method = typeMap[type]
return conf
}
最后method从typeMap中取出,也就是上一节的内容,最后将整个完整的config返回
axios请求配置(拦截器,基本配置)
接着这边是实例,引入接口功能集成、类型、配置
设置接口的超时时间,configJWT是对请求头增加token标识
import reqUrlMap from './mapping';
import serviceType from './serviceType'
import {getConfig} from './serviceConfig'
axios.defaults.timeout = 500000;
axios.defaults.baseURL = '';
let $axios = axios.create();
const axiosXhr = axios.create();
function configJWT(config) {
let token = `this is my token`;
config.headers['Authorization'] = token;
return config;
}
请求拦截器
使用interceptors.request进行请求拦截,对config重新设置,并且拦截器处发生错误会进行抛错
$axios.interceptors.request.use(
config => {
let configGhost = configJWT(config);
return configGhost;
},
error => {
msg({
message: '请求异常,请联系管理员',
type: 'error'
});
return Promise.reject(error);
}
);
抛出axios请求实例
抛出一个异步函数接收,如果请求没有传入alias别名,则返回一个空对象,通过alias别名在mapping中获取接口类型最后把所有配置集成请求axios,这里的axios返回的是一个promise,所以这里用await便于我们请求doRequest请求可以用到then和catch
export default {
async doRequest({
alias = '',
query,
body,
params
} = {}) {
let cfg;
let url;
let type;
if (!alias) {
return {};
}
type = reqUrlMap[alias].type;
url = reqUrlMap[alias].url
url = `api/${url}`;
cfg = {
url,
...getConfig(type, query, body)
};
return await $axios(cfg);
}
}
请求例子
最后我们发送一个请求,发送的请求配置如下
http.doRequest({
alias:'aa-api',
data:{
areaID:'11',
arr:[{name:11,age:22}]
}
}).then((res)=>{
console.log(res)
})
token设置发送正常
但是我们看到返回的参数是嵌套了多层的,所以需要使用一个响应拦截器对responce进行处理
响应拦截
本来响应返回的是respone,现在我们返回的是responce.data,这样方便我们在请求处理返回内容的时候可以少写一层
$axios.interceptors.response.use(
response => {
return response.data
},
error => {
msg({
message: '请求异常,请联系管理员',
type: 'error'
});
return Promise.reject(error);
}
);