We use axios to encapsulate an API to facilitate processing of interface data and obtaining interfaces, what should we do when the data type of the interface does not meet the ResponseType specification? followed by sample code (with explanations and comments)
import axios, { AxiosError, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from '@ohos/axios'
import { auth } from './Auth'
import { promptAction } from '@kit.ArkUI'
import { logger } from './Logger'
// Increase the type
export interface APIErrorType {
message: string
msg: string
code: string
}
//The type of the interface returned
export interface TestResponseType<T> {
Test_data1: string;
data: T;
Test_data3: string
/**
* 10000-Succeed; Other - failed
*/
Test_code: string;
Test_msg: null;
}
// Base address
export const baseURL = 'http://test.changfunfly.com/'
// 1. Instantiate the Common Configuration
const instance = axios.create({
baseURL,
timeout: 5000
})
// 2. Configure a request interceptor
instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
// Unified Token Carrier
const user = auth.getUser()
// logger.info('Is the request interceptor triggered??')
config.headers.company_type = "2"
config.headers.sign = "himyidea_test_sign"
config.headers.envir = "HarmonyOS"
if (user?.token) {
// config.headers.Authorization = `Bearer ${user.token}`
config.headers.access_token = user.token
}
// logger.info('config.headers Request parameters:' + config.headers)
// logger.info('config.headers.Authorization Request parameter 2:' + JSON.stringify(config.headers.Authorization))
return config
}, (error: AxiosError) => {
return Promise.reject(error)
})
// 3. Add a response blocker
//Unified error handling, etc
instance.interceptors.response.use((response: AxiosResponse) => {
return response.data
}, (error: AxiosError<APIErrorType>) => {
// 3.1 Handle token expiration
if (error.response?.status === 401) {
promptAction.openToast({ message: 'If your login has expired, please log in again' })
auth.removeUser()
// Here to log out the information needs to be captured
// router.pushUrl({ url: 'pages/Index' })
}
// 3.2 The processing did not find the requested resource
else if (error.response?.status === 404) {
promptAction.openToast({ message: 'The requested resource does not exist' })
}
// 3.3There is no access to the processing
else if (error.response?.status === 403) {
promptAction.openToast({ message: 'There are no permissions' })
}
// 3.4 The request was processed in an incorrect way
else if (error.response?.status === 405) {
promptAction.openToast({ message: 'The request method is not allowed (e.g., POST access to interfaces that only support GET.))' })
}
3.5 Timeout for processing requests
else if (error.response?. status === 408) {
promptAction.openToast({ message: 'Request timed out' })
}
3.6 Handling throttling
else if (error.response?. status === 429) {
promptAction.openToast({ message: 'Requests are too frequent (throttling)' })
}
3.7 Handling Server Errors
else if (error.response?. status === 500) {
promptAction.openToast({ message: 'Server Error' })
}
3.8 Handling Gateway Errors
else if (error.response?. status === 502) {
promptAction.openToast({ message: 'Gateway Error' })
}
3.9 Processing Server Unavailable
else if (error.response?. status === 503) {
promptAction.openToast({ message: 'Server unavailable (ex: under maintenance)' })
}
3.10 Processing Gateway Timeout
else if (error.response?. status === 504) {
promptAction.openToast({ message: 'Gateway timeout' })
} else {
promptAction.openToast({ message: error?.response?.data.message })
}
return Promise.reject(error)
})
// Generic data object types of APIs
export interface HttpResponse<T> {
code: string
msg: string
result: T
}
export type ResponseType<T> = AxiosResponse<HttpResponse<T>>
export class RequestAxios {
// get -> params -> { params: {} }
static get<T>(url: string, config?: AxiosRequestConfig): Promise<ResponseType<T>> {
return instance.get<null, ResponseType<T>>(url, config)
}
static post<T, D>(url: string, data?: D): Promise<ResponseType<T>> {
return instance.post<null, ResponseType<T>, D>(url, data)
}
static delete<T>(url: string, config?: AxiosRequestConfig): Promise<ResponseType<T>> {
return instance.delete<null, ResponseType<T>>(url, config)
}
static put<T>(url: string, data?: object): Promise<ResponseType<T>> {
return instance.put<null, ResponseType<T>>(url, data)
}
static post_cf<T, D>(url: string, data?: D): Promise<CFResponseType<T>> {
return instance.post<null, CFResponseType<T>, D>(url, data)
}
// get -> params -> { params: {} }
static get_cf<T>(url: string, config?: AxiosRequestConfig): Promise<CFResponseType<T>> {
return instance.get<null, CFResponseType<T>>(url, config)
}
/**
* post_cf_object(You don't need to encapsulate the request parameters)
* @param url
* @param data
* @returns
*/
static post_cf_object<T>(url: string, data?: object): Promise<CFResponseType<T>> {
return instance.post<null, CFResponseType<T>>(url, data)
}
}
(Code explanation: The axios network request encapsulation library based on HarmonyOS mainly implements the following functions: create an instance with the basic URL and timeout settings through axios.create(); Fixed request headers such as company_type and sign are added to the request interceptor, and user tokens are dynamically injected. In the response interceptor, various HTTP error status codes (401/404/500, etc.) are systematically processed, promptAction is used to display friendly error prompts, and the token clearance operation is performed especially for the 401 state. The RequestAxios class provides typed request methods such as GET/POST/DELETE/PUT, and supports different response data structures (including standard format and TestResponseType special format) through generics, and finally realizes the unified configuration, identity authentication, error handling, and type-safe invocation of network requests. )
Top comments (0)