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-query
Let’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 authenticationAuth
In the class
In order to be used happily in this article, some special treatments have to be done, such as I addedstorage
Attributes, judge first when readingwindow
Whether it exists.
Encapsulation axios
I put all the codes about APIsrc/services
In 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 definedApiClient
Class, a bit imitating C#HttpClient
It 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 definedIntroduced
ApiClient
Object, call directlyrequest
The 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!