前端如何相对优雅管理api

  • 前端如何相对优雅管理api已关闭评论
  • 264 次浏览
  • A+
所属分类:Web前端
摘要

一般来说,项目由子模块组成,拿到后端提供过来的接口,一般也是按照子模块来分类提供的.请教一下各位,你们前端项目是如何管理api的?

一般来说,项目由子模块组成,拿到后端提供过来的接口,一般也是按照子模块来分类提供的.请教一下各位,你们前端项目是如何管理api的?

希望各位贴点你们的优秀代码段上来学习学习.

 

常见:

各个模块的api存放到单独的js文件里,返回一个请求实例promise对象

使用的时候根据需求引入相应的请求方法

// axios/request.js 文件:
/* 创建axios请求实例,并返回实例 代码就不贴上来了*/

// axios/apis/home.js 文件:  import request from "../request"; //获取菜单 export function getHomeNav(params) {   return request({      url: "/api/home/getNav",      params: params    });  }  //获取热门新闻  export function getHotNewsList(params) {    return request({      url: "/api/home/getHotNewsList",      params: params    });  }

// axios/apis/my.js 文件:    // 获取用户信息  export function getUserInfo(params) {    return request({      url: "/api/get/user/info",      params: params    });  }  // 更新用户信息  export function updateUserInfo(params) {    return request({      url: "/api/post/user/update",      data: params    });  }

// 使用文件:  import { getHomeNav, getHotNewsList } from '@/axios/apis/home.js'
import { getUserInfo, updateUserInfo} from '@/axios/apis/home.js'
 getHomeNav({}).then(res=>{     console.log(res)  });

 

个人在某个项目上,烦透了在使用的时候一个个api请求方法引入.花了点时间,改成了所有api直接挂在一个全局变量上.牺牲了点性能,但是使用起来爽歪歪的感觉.

假如axios/apis/home.js文件: export default {     //获取菜单     nav: {         url: "/api/home/getNav",         method: "get",         config:{timeout:50000} // 会覆盖到axios实例的config对应的属性     },     body: {         //getHotNewsList         getHotNewsList: {             url: "/api/home/getHotNewsList",             method: "get",         },         //getList         getList: {             url: "/api/home/getList",             method: "get",         },     }, }; 

 

全局引入所有API:

 import requireApi from '@/axios/index.js'

 const APIS  = requireApi();

 home里的api调用可以这样:

 APIS.home.nav({page:1,sizePages:20}).then(res=>{ ... })

 APIS.home.body.getHotNewsList({page:1,sizePages:20}).then(res=>{ ... })

假如另外有一个my的模块api,使用起来可以这样:

APIS.my.xxxx().then(res=>{ ... });

 
下面是实现代码段:
// 假如目前有两个模块的api,分别存放在home.js,my.js里
// axios/apis/home.js文件:
export default { //获取菜单 nav: { url: "/api/home/getNav", method: "get", config:{timeout:50000} // 会覆盖到axios实例的config对应的属性 }, body: { //getHotNewsList getHotNewsList: { url: "/api/home/getHotNewsList", method: "get", }, //getList getList: { url: "/api/home/getList", method: "get", }, }, };


// axion/apis/my.js文件:
export default { // 获取用户信息 getUserInfo: { url: "/api/get/user/info", method: "get", }, // 更新用户信息 updateUserInfo: { url: "/api/post/user/update", method: "post", }, };

 

 

// axios/index.js 文件:  import createApiFn from "./createApiFn"; /**  *  把api文件夹下的所有Api文件require进来,在逐个export出去  *  假如axios/apis/home.js文件:         export default {             //获取菜单             nav: {                 url: "/api/home/getNav",                 method: "get",                 config:{timeout:50000} // 会覆盖到axios实例的config对应的属性             },             body: {                 //getHotNewsList                 getHotNewsList: {                     url: "/api/home/getHotNewsList",                     method: "get",                 },                 //getList                 getList: {                     url: "/api/home/getList",                     method: "get",                 },             },         };   *  按需求引入:  *  import { home } from '@/axios/index.js'  *  home.nav({page:1,sizePages:20}).then(res=>{ ... })  *  home.body.getHotNewsList({page:1,sizePages:20}).then(res=>{ ... })  *   *  全局引入所有API:  *  import requireApi from '@/axios/index.js'  *  const APIS  = requireApi();  *  APIS.home.nav({page:1,sizePages:20}).then(res=>{ ... })  *  APIS.home.body.getHotNewsList({page:1,sizePages:20}).then(res=>{ ... })  */  /** // webpack let requireApi = () => {   let allApi = require.context("./apis/", false, /.js$/),       allApiFnObj = {};   allApi.keys().map((item) => {     allApiFnObj[item.replace(/(./|.js)/g, "")] = createApiFn(allApi(item).default);   });   return allApiFnObj; }; */  // vite let requireApi = () => {       let allApi = import.meta.globEager('./apis/*.js'),           allApiFnObj = {};       Object.keys(allApi).map((item) => {         const fileName = item.replace(/./apis/|.js/g, '');         allApiFnObj[fileName] = createApiFn(allApi[item].default);       });       return allApiFnObj;     };  export default requireApi;  // 需要手动把各个模块export出去 let { home, my } = requireApi(); export { home, my };

 

// axios/createApiFn.js文件:  import requestInstance from "./request";  const bindPromiseFn = (apiObj, args, config={}) => {   const params = {     method: apiObj.method || "get",     url: apiObj.url,     params: args,     config: apiObj.config || {},   };   params.config = {     ...params.config,     ...config   }   return requestInstance(params); }; /**  * 把apis对象转变成以字段名为方法名的对象  * 如:  * apis={  *   getDemo:{  *      url:"xxxx",  *      method: "get"  *   },  *   postDemo:{}  * }  * 执行方法后返回对象结构如下:  * {  *  getDemo:function(){},  *  postDemo:function(){}  * }  * @param {object} apis  */ const createApiFn = (apis) => {   var obj = {};   Object.keys(apis).map((key) => {     if (apis[key] && apis[key].url) {       obj[key] = (function (apiObj) {         /**          * args 请求入参          * config 请求配置相关信息,最终会传给实例axios.config          */         return function (args,config={}) {           return bindPromiseFn(apiObj, args, config);         };       })(apis[key]);     } else if ( apis[key] && !apis[key].url && Object.prototype.toString.call(apis[key]) === "[object Object]") {       obj[key] = createApiFn(apis[key]);     }   });   return obj; };  export default createApiFn;

 

// axios/request.js 文件:  import axios from "axios";  // 创建axios实例 const axiosInstance = (config = {}) => {   const _config = {     // baseURL: `${location.protocol}//${process.env.VUE_APP_BASE_API}`, //  `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。     timeout: 30000,   };   config = {      ..._config,      ...config    };   return axios.create(config); };  const requestInstance = (args) => {   let { method, url, params, config = {} } = args;   if (!url) {     return;   }   if (method === "get") {     params = { params: params };   }    const instance = axiosInstance(config);    instance.interceptors.request.use(     (config) => {       // config.headers["x-auth-token"] = getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改       return config;     },     (error) => {       return Promise.reject(error);     }   );    instance.interceptors.response.use(     (response) => {       const { status, statusText, data } = response       if (status === 200 || status === 304) {         return Promise.resolve(data);       } else {         return Promise.reject(statusText || "Error");       }     },     (error) => {       return Promise.reject(error);     }   );    debugger;   return instance[method](url, params, config); };  export default requestInstance;

 

//全局引入所有API使用方法: import requireApi from '../axios/index' const API  = requireApi(); API.my.updateUserInfo({name:'xiaomou'}).then(res=>{       console.log(res); }) APIS.home.body.getHotNewsList({page:1,sizePages:20}).then(res=>{ ... })  //按需求引入方法: import { home } from '@/axios/index.js' home.body.getHotNewsList({page:1,sizePages:20}).then(res=>{ ... })