跳至主要內容

基于 TS 对 axios 的封装和 api 自动生成

xlc520JavaJava大约 5 分钟约 1484 字

基于 TS 对 axios 的封装和 api 自动生成

随着前后端分离的开发模式越来越流行,前端需要通过 ajax 或 fetch 等技术与后端进行数据交互,而在这些技术中,axios 被广泛应用并得到了很好的反馈。但是,直接使用原生的 axios 在大型项目中可能存在重复和复杂度高的问题,因此有必要对它进行封装,同时,自动生成 api 也可以帮助我们节省开发时间和减少错误,本文将介绍基于 TypeScript 对 axios 的封装和 api 的自动生成。

1. 安装和引入 axios

我们首先需要安装 axios 并在项目中引入它,可以使用以下命令进行安装:

npm install axios --save

接下来,我们在需要使用的文件中引入 axios:

import axios from "axios";

2. 封装基础请求类

我们需要在 axios 的基础上进行进一步封装来达到定制化需求,我们可以创建一个基础请求类将公共的请求操作进行封装。

import axios from "axios";

class BaseRequest {
  private axiosInstance;

  constructor() {
    this.axiosInstance = axios.create({
      baseURL: "http://localhost:3000", // 后端接口地址
      timeout: 10000, // 请求超时时间
      headers: {
        "Content-Type": "application/json;charset=utf-8",
      },
    });
  }

  async GET(url: string, params?: any) {
    return await this.request("GET", url, params);
  }

  async POST(url: string, data: any) {
    return await this.request("POST", url, data);
  }

  async PUT(url: string, data: any) {
    return await this.request("PUT", url, data);
  }

  async DELETE(url: string, params?: any) {
    return await this.request("DELETE", url, params);
  }

  async request(method: string, url: string, data: any) {
    try {
      const response = await this.axiosInstance.request({
        method,
        url,
        data,
      });
      const res = response.data;
      return res;
    } catch (error) {
      console.error("request error:", error);
      throw error;
    }
  }
}

export default BaseRequest;

在此示例中,我们创建一个 BaseRequest 类,它具有基本的 GET、POST、PUT 和 DELETE 请求方法,这些方法调用 request 方法来创建 axios 请求。我们将 axios 实例化为 axiosInstance,并传递一些设置。然后,我们定义了一个 request 方法来处理所有类型的请求。在这里,我们使用 try-catch 块来捕获异常,并将响应数据返回给调用者。

3. 封装具体请求类

我们将基于 BaseRequest 类创建具体的请求类来执行特定类型的请求并获取响应进行处理。以下是一个示例类:

import BaseRequest from "./BaseRequest";

class UserRequest extends BaseRequest {
  async getUserInfo(userId: string) {
    const url = `/user/info/${userId}`;
    const data = await this.GET(url);
    return data;
  }

  async updateUserAvatar(userId: string, formData: FormData) {
    const url = `/user/avatar/${userId}`;
    const data = await this.POST(url, formData);
    return data;
  }
}

export default UserRequest;

在此示例中,我们创建了 UserRequest 类,并定义了 getUserInfo 和 updateUserAvatar 两个方法来处理 getUserInfo 和 updateUserAvatar 请求。这些方法使用 BaseRequest 类的相应方法来生成请求,并返回响应数据。

4. 自动化生成 API

手动编写每个请求函数并不是一个明智的选择,我们可以通过 node 脚本自动生成一整套对应的 api 文件,来将重复操作降到最小。我们可以定义一个 API 自动生成的代码模板,并在执行脚本时插入变量来生成对应的代码。以下是自动生成 api 文件的示例代码:

const fs = require("fs");
const path = require("path");

const apiTemplate = `import BaseRequest from "../BaseRequest";

class ##className## extends BaseRequest {
##methods##
}

export default ##className##;
`;

const methodTemplate = `  async ##apiName##(##params##) {
    const url = `##url##`;
    const data = await this.##method##(url, ##data##);
    return data;
  }`;

const apiConfig = [
  {
    className: "UserRequest",
    modules: [
      {
        apiName: "getUserInfo",
        url: "/user/info/:userId",
        method: "GET",
        params: "userId",
        data: "",
      },
      {
        apiName: "updateUserAvatar",
        url: "/user/avatar/:userId",
        method: "POST",
        params: "userId, formData",
        data: "formData",
      },
    ],
  },
];

apiConfig.forEach((config) => {
  let fileContent = apiTemplate.replace("##className##", config.className);
  let methods = "";
  config.modules.forEach((api) => {
    let methodContent = methodTemplate
      .replace("##apiName##", api.apiName)
      .replace("##url##", api.url)
      .replace("##method##", api.method)
      .replace("##params##", api.params)
      .replace("##data##", api.data);
    methods += methodContent + "\n";
  });
  fileContent = fileContent.replace("##methods##", methods);

  const filePath = path.join(__dirname, `${config.className}.ts`);
  fs.writeFileSync(filePath, fileContent);
});

在此示例中,我们首先定义了代码的两个模板:apiTemplate 和 methodTemplate。然后,我们定义了一个 apiConfig 数组,其中包含我们将要生成的 API 信息。后续的代码会遍历 apiConfig 数组,并使用 apiTemplate 和 methodTemplate 来生成具体的代码文件。相应的代码文件中就定义了我们的请求方法和相关的请求 url、请求数据和请求方式。

5. 总结

在本文中,我们基于 TypeScript 对 axios 进行了封装,使得我们可以方便地进行请求操作并处理响应数据。我们还展示了如何通过自动生成 api 的方式来减少代码的重复和降低出错的概率。封装 axios 和自动生成 api 是大型项目中的一种好的实践,可以提高项目的可读性和重用性,同时也有助于快速开发和迭代。

第二种

为了使用 TypeScript 对 Axios 进行封装,你可以创建一个名为 http.ts 的文件,其中包含以下内容:

import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';

class HttpClient {
  private instance: AxiosInstance;

  constructor(config: AxiosRequestConfig) {
    this.instance = axios.create(config);

    // 设置请求拦截器
    this.instance.interceptors.request.use(
      (config: AxiosRequestConfig) => {
        // 在发送请求之前做些什么
        // 例如:添加token
        return config;
      },
      (error) => {
        // 请求错误时做些什么
        return Promise.reject(error);
      }
    );

    // 设置响应拦截器
    this.instance.interceptors.response.use(
      (response: AxiosResponse) => {
        // 在then或catch中使用response.data
        return response.data;
      },
      (error) => {
        // 响应错误时做些什么
        return Promise.reject(error);
      }
    );
  }

  request<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.instance.request(config);
  }

  get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.get(url, config);
  }

  post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.post(url, data, config);
  }

  put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.put(url, data, config);
  }

  delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.delete(url, config);
  }
}

export default HttpClient;

在你的项目中,你可以创建一个 config.ts 文件,其中包含 axios 的默认配置:

import { AxiosRequestConfig } from 'axios';

const config: AxiosRequestConfig = {
  baseURL: process.env.VUE_APP_API_BASE_URL,
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json;charset=UTF-8',
  },
};

export default config;

最后,在你的入口文件 main.ts 中导入并实例化 HttpClient

import HttpClient from './http';
import config from './config';

const http = new HttpClient(config);

export default http;

现在,你可以在其他地方使用 http 实例来发起请求,例如:

import http from './http';

http.get('/users');

这样,你就成功地使用 TypeScript 对 Axios 进行了封装。