0.2.1 • Published 1 year ago

@ctsx/easyapi v0.2.1

Weekly downloads
-
License
ISC
Repository
github
Last release
1 year ago

@ctsx/easyapi

前端开发 API 系统,支持数据适配器,mock 生成器,支持 RESTFul 方式接口,可以普遍在 vue 或者 react 的 api 相关模块中使用

接口管理

前言

接口是前后端交互的核心工作,是业务的基础,接口的定义直接影响前端功能的开发和数据的使用,为了更好的进行接口管理,满足前端对接口使用的各种便利操作,特通过此模块完成对接口的各种管理

功能描述

  1. 接口命名空间
  2. 接口全局拦截处理
    1. 请求拦截
    2. 响应拦截
    3. 错误拦截
  3. 接口成功后的自动提示
  4. 接口错误后的自动提示
  5. 请求数据/响应数据自动适配转化
  6. 接口响应数据 mock
  7. 接口签名支持,满足数据校验/开发自动提示
  8. 接口缓存支持
  9. 接口调试日志

使用方式

  1. 设置拦截器
  2. 声明接口
  3. 使用接口

具体实践见 template 目录

设置拦截器

import easyapi from '@ctsx/easyapi';
import Cookies from 'js-cookie';
import adapter from './adapter';
import { ExtendConfig, ExtendMeta } from './types';

const { define } = easyapi<ExtendConfig, ExtendMeta>({
  mode: 'development',
  axios: {
    baseURL: '.',
  },
  logger: true,
  delay: 300,
  mockForce: true,

  // 设置then返回的数据为data字段,假如需要返回完整的数据,请使用fully
  resolveType: 'data',

  // 对响应的数据做处理,对resData和msg字段转成标准化的data和message
  dataNormalizer(ctx) {
    const original = ctx.responseObject?.data;
    if (original) {
      ctx.responseObject.data = {
        code: original.code,
        data: original.resData,
        message: original.msg,
      };
    }
  },

  // 请求拦截器
  request(ctx) {
    adapter.request(ctx);

    const { config } = ctx;

    // // 启动mockjson
    // if (typeof config.mockjson === 'string') {
    //   config.mockBody = () => {
    //     return mockJSON(config.mockjson, ctx.payload);
    //   };
    // }

    // 加认证状态token
    const csrfToken = Cookies.get('token');
    if (csrfToken) {
      ctx.setHeader('x-csrf-token', csrfToken);
    }

    // 请求前置拦截器,主要用于不同接口满足不同的处理需求
    config.beforeRequest?.(ctx);
  },

  // 响应拦截器
  response(ctx) {
    const { responseObject } = ctx;

    // 二进制数据,不对响应数据进行处理
    if (responseObject.config.responseType === 'arraybuffer') {
      return;
    }

    // 响应前的拦截器
    ctx.config.beforeResponse?.(ctx);

    // 对响应的数据做处理
    const { data, headers } = responseObject;
    const { code } = data;

    // // 储存鉴权码
    // if (headers?.token) {
    //   token = headers.token;
    // }

    // 其他错误
    if (code !== 200 && code !== 0) {
      throw Error(data.message || (data as any).msg);
    }
  },

  // 成功响应拦截器
  success(ctx) {
    adapter.success(ctx);

    const { config } = ctx;
    const { showSuccess } = config;
    const { data } = ctx.responseObject.data;

    if (showSuccess === true) {
      // console.info(data.message || '操作成功');
    } else if (typeof showSuccess === 'string') {
      // console.info(showSuccess);
    }
  },

  // 错误响应拦截器
  failure(ctx) {
    const { error, config, responseObject } = ctx;
    const responseData = responseObject?.data;

    // 阻止默认的错误处理
    if (config.showError === false) {
      return;
    }

    // 自定义的错误信息
    if (typeof config.showError === 'string') {
      // message.error(config.showError);
    }
    // 常规的错误处理,显示错误信息
    else {
      // message.error(error.message.substr(0, 100));
    }
  },
});

export { define };

声明接口

import { define } from '@api';

// 请求参数签名
interface Payload {
  page: number;
  pageSize: number;
}

// 响应数据签名
interface ResponseData {
  list: Array<{
    id: number;
  }>;
}

// 导出接口
export const getSomeList = define<Payload, ResponseData>({
  url: 'api/getSomeList',
  method: 'post',
});

使用接口

import { getSomeList } from '@api';

getSomeList({ page: 1, pageSize: 20 }).then((data) => {
  //..
});

模板文件

请修改 template 目录下的文件使用