Detailed Explanation of Interface Request Management Based on Typescript and Axios

  • 2021-11-14 05:01:17
  • OfStack

Directory thought request interception Response interception Defining a request using httpClient. ts Requesting an interface in a component Summarize

This paper mainly introduces the interface request encapsulation based on TS and AXIOS

Train of thought

Request interception

Add 1 parameters to the request header, such as token, uid, etc Judge the login status of the user. If there is no login, jump login directly Processing request data converts the data format of the sending request, json → urlencoded (optional)

Response interception

Judge the service status code of the back-end response and carry out different processing For example, if the user login status expires, jump login directly Error reporting prompt of system 1

Write out the routine code first:


import axios, {
    AxiosInstance,
    AxiosResponse,
    AxiosRequestConfig,
    AxiosError
} from 'axios'
export default abstract class HttpClient {
    protected readonly instance: AxiosInstance

    public constructor(baseURL = '/api', timeout = 1000 * 120) {
        this.instance = axios.create({
            baseURL,
            timeout
        })
        // 1.  Request interceptor 
        this._initializeRequestInterceptor()
        // 2.  Response interceptor 
        this._initializeResponseInterceptor()
    }
    private _initializeRequestInterceptor = () => {
        this.instance.interceptors.request.use(
            this._handleRequest,
            this._handleError
        )
    }
    private _handleRequest = (config: AxiosRequestConfig) => {}
   
    private _initializeResponseInterceptor = () => {
        this.instance.interceptors.response.use(
            this._handleResponse,
            this._handleError
        )
    }
    private _handleResponse = (response: AxiosResponse) => {}
    protected _handleError = (error: AxiosError) => Promise.reject(error)
}

Simply talking about the above code, we created an HttpClient class for request interface, defined baseURL and timeout timeout in constructor, and defined request interception method and response interception method at the same time.

At this point, the process of initiating 1 interface is as follows:

Request interception is invoked before the request is sent Send interface, network request appears Interface response, call response interception Respond to the front-end program and execute the corresponding logic

Request interception

The following is the detailed logic. When requesting interception, you can do the following things:

Add 1 parameters to the request header, such as token, uid, etc Judge the login status of the user. If there is no login, jump login directly Processing request data converts the data format of the sending request, json → urlencoded (optional)

     private _handleRequest = (config: AxiosRequestConfig) => {
        //1.  Add a custom request header 
        config.headers['Authorization'] = 'my token'
        config.headers['mobile'] = 'my mobile'
        //2.  Determine whether to log in (Determine whether there is toke ) 
        
        //3.  Convert data format 
        config.data = qs.stringify(config.data)
        return config
    }

Response interception

After getting the response, the process is as follows:

Judge the service status code of the back-end response and carry out different processing If the user login status expires, jump login directly Error reporting prompt of system 1 Save token

 //  Response interceptor 
    private _handleResponse = (response: AxiosResponse) => {
        const { data, headers } = response

        //1.-- Object that handles the response token, Save token
        const token = headers['authorization']
        if (token) {
            this._saveToken(token)
        }
       
        //2. -- Processing response code , Here try-catch1 If the backend has an interface that does not return code, Direct return 
        try {
            const code = data.code,
            message = data.desc || data.msg
            const isSucceed = this._handleResCode(code, message, url)
            if (isSucceed) {
                return Promise.resolve(data)
            } else {
                return Promise.reject(message)
            }
        } catch (error) {
            return Promise.resolve(data)
        }
       
    }
    // Save token
    private _saveToken(token: string) {
        const USER = getModule(UserModule)
        USER.setToken(token)
    }
    private _handleResCode(code: number, message: string, url: string) {
        if (code === 0) {
            //  Request succeeded 
            return true
        } else if (code===4000) {
            // token Failure , Jump back to the login interface 
            Vue.prototype.$message.error(' Identity information has expired, please log in again ')
            router.push({ name: 'login' })
            return false
        } else {
            //  In other cases, all prompt message Information 
            Vue.prototype.$message.error(message)
            return false
        }
    }

Defining a request using httpClient. ts

It is recommended that the files related to the request be defined under the @ /api directory as follows


httpClient.ts
user.ts
uti.ts

Define requests in corresponding files, considerations

All request classes need to inherit from HttpClient, and HttpClient has done some work of intercepting and processing requests and responses The data of request response needs to provide type, which is defined in @/types/xxx file, and one module corresponds to one file. Only when the type is provided will there be a code prompt

import HttpClient from './HttpClient'
import { AlarmItemType } from '../types/test'
import { BaseResType } from '../types/index'

class UtilApi extends HttpClient {
   // For example, the response returned in the background   res={code:xxx,data:xxx,token:xxx,desc:xxx}
    // You first need to define  res.data  Type of   I.e. get The first part of 1 Parameters   AlarmItemType
    // You then need to define the type of the entire response   I.e.  BaseResType<AlarmItemType>
    public getAlarmById = (id: string) =>
        this.instance.get<AlarmItemType, BaseResType<AlarmItemType>>(
            `/realtime/alarms/queryByAlarmId/${id}`
        )
}

export const UTIL_API = new UtilApi()

Requesting an interface in a component

Type the key word of the request module in the component that needs to send the request, such as USER_API. If the plug-in TypeScript Importer is installed, there will be a corresponding module import prompt. At this time, enter Enter to import the corresponding module.


<template>
    <section> Request data :{{ alarmData }}</section>
</template>

<script lang="ts">
import { UTIL_API } from '@/api/utilApi'
import { Vue, Component } from 'vue-property-decorator'
@Component({
    components: {}
})
export default class TestRequest extends Vue {
    alarmData = {}
    async getAlarmData() {
        const res = await UTIL_API.getAlarmById('alarmIdc7e9bd47')
        if (res.code == 0) {
            this.$message.success(' Request succeeded ')
            this.alarmData = res.data
        }
    }
    mounted() {
        this.getAlarmData()
    }
}
</script>
<style lang="scss" scoped></style>

Summarize


Related articles: