震惊,难道只有我是这么管理api的?

7,445 阅读2分钟

一.起点

看了些管理api的文章,和自己大有不同,抛砖引玉,望各位口下留德,切勿不识好歹。(狗头)

本文代码顺序从调用开始,层层向里展示。

二.使用效果如下

1.添加API

2.添加API .d.ts注释文件

其实 1/2可以统一,但是由于项目不是纯ts的,就懒得重构了。文章后面的注释.d.ts文件就不再截图了

三.API请求层封装

1.统一处理数据

由于项目中,接口数据统一有封装,封装格式如下

{
 status:number;//接口状态
 msg:string;//接口信息,一般都是异常信息
 data:any;//实际获取的数据,需要拆箱获取
}
  • 为了方便,数据校验异常时,抛出异常,axios 拦截器拦截到时,进行notify/dialog进行提示。
  • 其中还自定义了一个APIStatusError对象,用于自定义处理错误信息

2.封装axios请求类型

还包括上图的上传文件function postFileForm

四.全局axios配置

此处没什么好说的,就是一些通用的处理,以及拦截http api中返回的 异常数据

import axios from "axios";
import { API_SUCCESS, NocaughtErrorUrl } from "@api/CONSTANT";
import { curEnvAPIURL } from "../statics/config/config";
import { SessionStorage } from "quasar";

export default ({ Vue, store }) => {
  let vueInstance = new Vue();
  
  //自定义状态map
  let CustomizeStatus = { SessionExpired: 901 };
  
  //通常http code 对应的message
  const codeMessage = {
    200: "服务器成功返回请求的数据。",
    201: "新建或修改数据成功。",
    202: "已有请求已经进入后台排队(异步任务)。",
    204: "删除数据成功。",
    400: "发出的请求有错误,服务器没有进行新建或修改数据的操作。",
    401: "用户没有权限(令牌、用户名、密码错误)。",
    403: "用户得到授权,但是访问是被禁止的。",
    404: "发出的请求针对的是不存在的记录,服务器没有进行操作。",
    406: "请求的格式不可得。",
    410: "请求的资源被永久删除,且不会再得到的。",
    422: "当创建一个对象时,发生一个验证错误。",
    500: "服务器发生错误,请检查服务器。",
    502: "网关错误。",
    503: "服务不可用,服务器暂时过载或维护。",
    504: "网关超时。"
  };

  function axiosInit() {
    let baseURL = apiUrl;

    //一些默认设置
    axios.defaults.baseURL = curEnvAPIURL;//当前环境的api url前缀,由于本项目上线服务器较多,为方便,统一在此处理。
    axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
    axios.defaults.withCredentials = true;
    axios.defaults.timeout = 2 * 60 * 1000;

    axios.interceptors.request.use(
      config => {
        return config;
      },
      error => {
        console.error(error);
      }
    );

    axios.interceptors.response.use(
      response => {
        vueInstance.$q.loading.hide();
        let result = response.data;
        if (result.status === CustomizeStatus["SessionExpired"]) {
          //-----> 用户状态超时回调
          return response;
        }
        
        //http code异常时弹出dialog
        if (response.status !== 200) {
          vueInstance.$q.dialog({
            title: "错误",
            message: `请求失败:${codeMessage[response.status]}`
          });
          return response;
        }
        
        //TODO:异常埋点,待对接api
        
        //项目中存在某些不需要捕捉异常的api,此处特殊处理
        if (
          result.status !== API_SUCCESS &&
          NocaughtErrorUrl.every(_ => !response.config.url.includes(_))
        ) {
          vueInstance.$q.dialog({
            title: "错误",
            message: `${result.status}${result.msg}` || `请求异常,CODE:${result.status}`
          });
        }
        return response;
      },
      error => {
        let errorMsg;
        
        //接口返回的{status:number;msg:string,data:any}中的status异常时,dialog提示
        try {
          let statusCode = error.response.status;
          errorMsg = `${statusCode}${codeMessage[statusCode]}`;
        } catch {
          errorMsg = error.message;
        }
        //优先提示状态码对应的错误
        if (!errorMsg) {
          errorMsg = error.message;
        }

        vueInstance.$q.dialog({
          title: "错误",
          message: `请求失败:${errorMsg}`
        });

        return Promise.reject(error);
      }
    );

    Vue.prototype.$http = axios;
  }
  axiosInit();
};

五.项目API目录

各有所好,本人目录如下

六.感悟

项目支持的话,可能还是纯ts会好些吧?