SoFunction
Updated on 2025-04-08

Calling with Axios encapsulated backend interface in TypeScript project

Preface

I originally wanted to post development notes, but I found that there were too many things involved, so I should split them out and post them~

This article records the process of encapsulating axios in the TypeScript project. I had already done it when developing StarBlog-Admin, but it was JavaScript at that time, and it was still a bit different from TypeScript.

In addition, when I was following the document development, I noticed that the official document recommended to use@tanstack/react-queryLet’s encapsulate the operation of the request class. After a brief look at the document, I feel it’s very good. Next, I will practice it in the project.

Define configuration

Create a global configuration first.src/utilities/

export default class Global {
  static baseUrl = .NEXT_PUBLIC_BASE_URL
}

This is in the project, the environment variables specified by next can be used, and other projects can be modified by themselves.

Encapsulation auth

The authentication part has something to do with axios, but it doesn't have much to do with it. However, because it needs to be used in the axios package, I will post it together.

Createsrc/utilities/document

/**
  * Login information
  */
export interface LoginProps {
  token: string
  username: string
  expiration: string
}

/**
  * Certification and authorization tools
  */
export default abstract class Auth {
  static get storage(): Storage | null {
    if (typeof window !== 'undefined') {
      return 
    }
    return null
  }

  /**
      * Check if you are logged in
      * @return boolean
      */
  public static isLogin() {
    let token = ?.getItem('token')
    let userName = ?.getItem('user')

    if (!token ||  === 0) return false
    if (!userName ||  === 0) return false
    return !();
  }

  /**
      * Check if the login expires
      * @return boolean
      */
  public static isExpired = () => {
    let expiration = ?.getItem('expiration')
    if (expiration) {
      let now = new Date()
      let expirationTime = new Date(expiration)
      if (now > expirationTime) return true
    }

    return false
  }

  /**
      * Read the saved token
      * @return string
      */
  public static getToken = () => {
    return ?.getItem('token')
  }

  /**
      * Save login information
      * @param props
      */
  public static login = (props: LoginProps) => {
    ?.setItem('token', )
    ?.setItem('user', )
    ?.setItem('expiration', )
  }

  /**
      * Logout
      */
  public static logout = () => {
    ?.removeItem('token')
    ?.removeItem('user')
    ?.removeItem('expiration')
  }
}

I put all the logic related to authenticationAuthIn the class

In order to be used happily in this article, some special treatments have to be done, such as I addedstorageAttributes, judge first when readingwindowWhether it exists.

Encapsulation axios

I put all the codes about APIsrc/servicesIn the directory.

Createsrc/services/The file, the code is relatively long and is introduced in chunks. You can see that all configurations have more configurations than the previous JavaScript versions, which are very friendly to IDE automatic completion.

Import first

import axios, {AxiosInstance, AxiosRequestConfig, AxiosResponse, CreateAxiosDefaults} from "axios";
import Global from '@/utilities/global'
import Auth from "@/utilities/auth";

Axios configuration

Define the configuration of axios

const config: CreateAxiosDefaults<any> = {
  method: 'get',
  // Basic url prefix  baseURL: `${}/`,
  // Request header information  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  },
  // Parameters  data: {},
  // Set the timeout time  timeout: 10000,
  // Carry a certificate  withCredentials: true,
  // Return data type  responseType: 'json'
}

Unified interface return value

Set a unified interface return value, which is the same as the one I encapsulated in the StarBlog backend. Now it is basically the standard return value for me writing the backend, and it has also been released.nuget package can quickly introduce this unified return value component.

// Unified interface returns valueexport interface ApiResponse {
  data: any
  errorData: any
  message: string
  statusCode: number
  successful: boolean
}

DefinitionApiClient

Finally, it's definedApiClientClass, a bit imitating C#HttpClientIt tastes inside

This uses axios interceptor. When making a request, add authentication information to the header, and check if there is any error when returning. If it is 401 unauthorized, it will jump to the login page.

export class ApiClient {
  private readonly api: AxiosInstance
  constructor() {
     = ({
      ...config,
    })
    (
      config => {
         = `Bearer ${()}`
        return config
      },
      error => {
        return error
      })
    (
      response => {
        return response
      },
      error => {
        let reason = error
        if (error && ) {
          if () {
            reason = 
            if (!)  = 
          }
          if ( === 401) {
             = '/login'
          }
        }
        return (reason)
      }
    )
  }
  public request(options: AxiosRequestConfig): Promise<ApiResponse> {
    return new Promise((resolve, reject) => {
      (options).then((res: AxiosResponse<ApiResponse>) => {
        resolve()
        return false
      }).catch(error => {
        reject(error)
      })
    })
  }
}
export const api = new ApiClient()
export default api

The code is simpler than what I used to use in StarBlog-Admin before, and I want to use as little code as possible to implement the required functions.

Write specific interface calls

I write all interface calls as service (this is the backend thinking)

Here, take the SMS interface as an example

Createsrc/services/File, from the definedIntroducedApiClientObject, call directlyrequestThe method is over.

The parameter type isAxiosRequestConfig, I feel that it is more comfortable than the interface that was modified with Antd Pro before.

import {api} from './api'
export class SmsChannel {
  static local = 0
  static aliyun = 1
  static tencent = 2
}
export default abstract class CommonService {
  public static getSmsCode(phone: string, channel: number = ) {
    return ({
      url: `api/common/getSmsCode`,
      params: {phone, channel}
    })
  }
}

summary

This way, the packaging is much more comfortable than before StarBlog-Admin. Unfortunately, the previous project used TypeScript.

That's it, most of the content is still in development notes.

References

  • /zh/docs/interceptors
  • /query/latest/docs/react/overview

This is the article about matching Axios encapsulated backend interface calls in TypeScript projects. For more related content on Axios encapsulated backend interface calls, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!