npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@itshixun/qst-request-lib

v1.1.11

Published

QST接口请求工具库

Downloads

5

Readme

@itshixun/qst-request-lib

QST接口请求工具库

1. 常用类型和枚举定义:

  • QstResult: 约定的数据响应类型
    /** 约定的常规接口返回数据结构体 */
    export interface QstResult<T> {
      /** http状态码 3位数 比如200、401、500等 */
      status: number;
      /** 扩展状态码 7位数 比如2000000 4010000 4000297 5000000等 */
      code: number;
      /** 成功标识 */
      success?: boolean;
      /** 消息 */
      message?: string;
      /** 返回的数据 */
      data?: T;
      /** 额外的返回数据,比如用户中心的extras.failureCount,返回登录错误的次数 */
      extras?: Record<string, unknown>;
    }
  • QstPagination: 约定的分页数据类型
    /** 约定的分页数据结构 */
    export interface QstPagination<T> {
      /** 总条数 */
      total: number;
      offset: number;
      limit: number;
      /** 当前页码 */
      pageNumber: number;
      /** 每夜条数 */
      pageSize: number;
      /** 数据数组 */
      rows: T[];
    }
  • ContentTypeEnum: ContentType类型枚举
    /** request contentType */
    export enum ContentTypeEnum {
      /** json */
      JSON = 'application/json;charset=UTF-8',
      /** form-data qs */
      FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8',
      /** form-data upload */
      FORM_DATA = 'multipart/form-data;charset=UTF-8',
    }

2. aioxs请求封装方法:requestWrapper

封装常规axios请求方法:requestWrapper:提炼通用的响应处理和错误提示,剥离AxiosResponse<T>封装并返回T类型的数据,业务端通常不需要再进行Promise.catch,仅需要处理必要的响应结果,除非在处理响应结果时有可能抛出业务逻辑相关错误时,再通过Promise.catch进行处理。

2.1 选项设置

在使用requestWrapper方法前,首先要进行选项设置。请求封装方法的选项类型RequestWrapperOption定义如下:

/** 请求封装方法的选项类型定义 */
export interface RequestWrapperOption<T = any> {
  /**
   * 自定义错误处理方法,仅在需要特殊处理的接口请求时使用此方法,作为requestWrapper中默认错误处理方法的补充
   * 要求保持返回的错误类型仍为AxiosError,保证错误信息在Promise链中的延续和可追溯
   */
  resolveError?: (err: AxiosError<T>) => AxiosError<T>;
  /** 显示错误消息提示的方法 */
  handleMessage?: (msg: string, err?: AxiosError<T>) => void;
  /** 错误已处理标志位,默认AxiosError.code === 'handled'时,表示该错误已处理,后续错误处理中判断code==='handled'时,不再弹窗错误提示,避免重复弹出 */
  handledCode?: string;
  /** 处理401(需要登录)的方法 */
  handle401?: (err: AxiosError<T>) => void;
  /** 处理403(无权限需要登录)的方法 */
  handle403?: (err: AxiosError<T>) => void;
  /** aixos实例,使用qstRequest的get/post等便捷请求别名时,需要传入该实例,否者默认使用aixos静态实例 */
  axiosInstance?: AxiosInstance;
}

我们可以通过setDefaultRequestWrapperOption设置requestWrapper方法的全局默认选项,比如:

setDefaultRequestWrapperOption({
  /** 使用element-plus的Message组件弹出错误提示消息 */
  handleMessage: (msg: string) => ElMessage.error(msg),
  /** 默认error.code 为 handled 时,表示错误已处理,不需要再弹出提示 */
  handledCode: 'handled',
  /** 401时跳转到登录页 */
  handle401: () => router.replace({ name: 'login' }),
  /** 403时无权限,跳转到登录页 */
  handle403: () => {
    ElMessage.error('当前登录角色无权限,请重新登录');
    logout();
    router.replace({ name: 'login' });
  },
  /** 常规的请求错误在requestWrapper中已做处理,一般不需要此处自定义resolveError方法,这里可以不做设置 */
  resolveError: (err: AxiosError<unknown>) => err,
  /** 设置qstRequest使用的默认axios实例 */
  axiosInstance: mainInstance,
});

2.2 调用方法

一个常规的axios请求流程,大致如下:

/** axios请求示例 */
axios
  .get<QstResult<ResData>>('/api/xxx')
  .then((res: AxiosResponse<QstResult<ResData>>) => {
    // 处理返回数据,取得res.data.data
    const data = getResult(res);
    return data;
  })
  .catch((err: AxiosError<QstResult<ResData>>) => {
    // 处理错误信息,弹出错误消息
    handleError(err);
    return Promise.reject(err);
  });

我们通过requestWrapper方法,提炼通用的响应处理和错误提示,剥离AxiosResponse<T>封装并返回T类型的数据,业务端通常不需要再进行Promise.catch,仅需要处理必要的响应结果,除非在处理响应结果时有可能抛出业务逻辑相关错误时,才通过Promise.catch进行处理。上面的方法,使用requestWrapper方法的示例如下:

/** 使用requestWrapper封装请求,此处使用默认设置,不再传入RequestWrapperOption选项 */
requestWrapper<QstResult<ResData>>(() => axios.get('/api/xxx')).then((res: QstResult<ResData>) => {
  return res.data;
});

上面的例子,经过requestWrapper处理后,Promise.then可以直接取得剥离AxiosResponse封装的响应数据。同时所有的常见请求错误,都已经在requestWrapper内部做了处理,如果确定Promise.then中不会抛出业务相关的错误,就不需要再使用Promise.catch进行错误处理了。

针对具体的接口,我们也可以传入专门针对该接口的RequestWrapperOption选项,从而使不同的接口可以获得各自不同的处理方式。比如在请求登录接口时,如果返回401说明登录接口本身的后端逻辑出错了,我们给出一个服务端错误的提示;另外我们希望登录接口使用原生alert的方式提醒用户。我们可以像下面这样,调用requestWrapper方法时传入RequestWrapperOption选项:

requestWrapper<QstResult<ResData>>(
  () => axios.post('/api/login', { loginData }),
  // 传入RequestWrapperOption,会通过Object.assign合并默认的RequestWrapperOption
  {
    handle401: () => alert('服务端错误:登录接口返回401!'),
    handleMessage: (msg: string) => alert(msg),
  }
).then((res) => {
  // 保存登录token
  setToken(res.data.accessToken);
  // 登录成功的后续处理...
});

通过setDefaultRequestWrapperOption设置全局选项,并且具体接口也可以在调用requestWrapper时传入不同的配置选项,可以实现:大部分接口请求使用统一的错误处理/错误提醒/401登录跳转等方法的同时,部分特殊接口使用自定义的错误处理/错误提醒/401状态处理方法。

3 仿aixos的请求别名

基于requestWrapper方法,我们构建了qstRequest对象,进一步封装了请求别名(get/post等)方法。我们可以像使用axios的便捷请求别名方法一样,以更简洁和符合使用习惯的方式进行接口请求。比如上面2.2 调用方法的示例:

/** 使用requestWrapper封装请求,此处使用默认设置,不传入RequestWrapperOption选项 */
requestWrapper<QstResult<ResData>>(() => axios.get('/api/xxx'));

我们也可以使用便捷请求别名进行请求,如下所示:

/** 使用qstRequest.get请求别名,此处使用默认设置,不传入RequestWrapperOption选项 */
qstRequest.get<QstResult<ResData>>('/api/xxx');

上述示例使用全局设置的默认RequestWrapperOption选项。如果某个特定接口使用另外的aixos实例进行请求,我们可以如下例这样,传入RequestWrapperOption选项,针对具体请求进行特殊配置:

qstRequest.post<QstResult>('/api/xxx/save', data, config, {
  // 针对本接口,使用名为"mySaveInstance"的axios实例进行请求
  axiosInstance: mySaveInstance,
  // 配置本接口不弹出错误提示消息,仅在控制台打印错误信息
  handleMessage: (msg: string) => {
    console.error(msg);
  },
});

注意:axios中AxiosInstance的定义,在v1.5.x和1.6.x中不同,因此如果您使用typescript开发,在配置RequestWrapperOption的axiosInstance时,需要安装最新的axios版本(目前 1.6.1),才可保证ts类型正确。

qstRequest的请求方式别名列表

qstRequest: {
  get<T = any, D = any>(url: string, config?: AxiosRequestConfig<D>, option?: RequestWrapperOption<T>): Promise<T>;
  delete<T = any, D = any>(url: string, config?: AxiosRequestConfig<D>, option?: RequestWrapperOption<T>): Promise<T>;
  post<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig, option?: RequestWrapperOption<T>): Promise<T>;
  put<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig, option?: RequestWrapperOption<T>): Promise<T>;
  patch<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig, option?: RequestWrapperOption<T>): Promise<T>;
  postForm<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig, option?: RequestWrapperOption<T>): Promise<T>;
  putForm<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig, option?: RequestWrapperOption<T>): Promise<T>;
  patchForm<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig, option?: RequestWrapperOption<T>): Promise<T>;
}

4 取得Axios原始响应数据AxiosResponse

上述工具(requestWrapper和qstRequest)帮助我们剥离AxiosResponse结构,直接返回T类型的数据,方便进行后续的数据处理;但是有些特殊情况下需要获取完整的AxiosResponse数据,比如要获取 response headers 中某个字段的值。这里我们通过requestWrapperRaw的方法,或者qstRequestRaw对象的get/post等请求别名,来获取Axios的原始响应数据:

/** 使用requestWrapperRaw封装请求,返回原始的Axios响应数据,即AxiosResponse<ResponseData>类型的数据 */
requestWrapperRaw<ResponseData>(() => axios.get('/api/xxx'));

/** 同样,使用qstRequestRaw下定义的请求方法别名,返回原始Axios响应数据 */
qstRequestRaw.get<ResponseData>('/api/xxx');