Xi-Yuer

Xi-Yuer

github

Axiosリクエスト

Axios を基にした汎用リクエストのラップ#

Type.d.ts#

// type
import type {
    AxiosRequestConfig,
    InternalAxiosRequestConfig,
    AxiosInterceptorOptions,
    AxiosResponse,
} from 'axios'

// インターセプターの拡張
export interface RequestConfig extends AxiosRequestConfig {
    requestInterceptor?: {
        onFulfilled?: (
            value: InternalAxiosRequestConfig,
        ) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>
        onRejected?: ((error: any) => any) | null
        options?: AxiosInterceptorOptions
    }

    responseInterceptor?: {
        onFulfilled?: (value: AxiosResponse) => AxiosResponse
        onRejected?: ((error: any) => any) | null
        options?: AxiosInterceptorOptions
    }
}

export type InterceptorType = Partial<
    Pick<RequestConfig, 'requestInterceptor' | 'responseInterceptor'>
>

export interface IResponse<T = any> {
    data: T
    message: string
    statusCode: number
    timestamp: Date
}

リクエストクラス#

// request
import axios, {
    type AxiosInstance,
    type AxiosResponse,
    type CancelTokenSource,
} from 'axios'
import type { IResponse, InterceptorType, RequestConfig } from './type'

class Request {
    Instance: AxiosInstance | null
    constructor(
        // インスタンスのリクエスト基本パス
        private readonly baseURL: string,
        // インスタンスのリクエストタイムアウト時間
        private readonly timeOUT: number,
        // インスタンスのインターセプター
        private readonly interceptor?: InterceptorType,
        // キャンセルトークン
        private cancelTokenSource: CancelTokenSource | null = null,
    ) {
        // インスタンスを作成
        this.Instance = axios.create({
            baseURL: this.baseURL,
            timeout: this.timeOUT,
        })
        // インスタンスのリクエストインターセプトを設定
        if (this.interceptor?.requestInterceptor) {
            this.Instance.interceptors.request.use(
                this.interceptor.requestInterceptor.onFulfilled,
                this.interceptor.requestInterceptor.onRejected,
                this.interceptor.requestInterceptor.options,
            )
        }
        // インスタンスのレスポンスインターセプトを設定
        if (this.interceptor?.responseInterceptor) {
            this.Instance.interceptors.response.use(
                this.interceptor.responseInterceptor.onFulfilled,
                this.interceptor.responseInterceptor.onRejected,
                this.interceptor.responseInterceptor.options,
            )
        }
    }
    // インスタンスメソッド request
    public request<T = AxiosResponse<any>>(config: RequestConfig): Promise<T> {
        return new Promise<T>((resolve, reject) => {
            // 単一インターフェースのリクエストインターセプト
            if (config.requestInterceptor) {
                this.Instance?.interceptors.request.use(
                    config.requestInterceptor.onFulfilled,
                    config.requestInterceptor.onRejected,
                    config.requestInterceptor.options,
                )
            }
            // 単一インターフェースのレスポンスインターセプト
            if (config.responseInterceptor) {
                this.Instance?.interceptors.response.use(
                    config.responseInterceptor.onFulfilled,
                    config.responseInterceptor.onRejected,
                    config.responseInterceptor.options,
                )
            }

            this.cancelTokenSource = axios.CancelToken.source()
            this.Instance?.request<T>({
                ...config,
                cancelToken: this.cancelTokenSource.token,
            })
                .then((res) => {
                    resolve(res as any)
                })
                .catch((err) => {
                    reject(err)
                })
        })
    }

    // リクエストをキャンセル
    public cancelRequest(): void {
        if (this.cancelTokenSource) {
            this.cancelTokenSource.cancel('リクエストをキャンセル')
        }
    }

    public get<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'GET', ...config })
    }
    public post<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'POST', ...config })
    }
    public delete<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'DELETE', ...config })
    }
    public patch<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'PATCH', ...config })
    }
    public put<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'PUT', ...config })
    }
    public head<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'HEAD', ...config })
    }
    public options<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'OPTIONS', ...config })
    }
    public trace<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'TRACE', ...config })
    }
    public connect<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'CONNECT', ...config })
    }
}

使用方法#

/**
 *
 * ================================================================================
 * ===================================テストコード=====================================
 * ================================================================================
 *
 */
const instance = new Request('https://xiyuer.club/api/v1', 10000, {
    requestInterceptor: {
        onFulfilled(config) {
            console.log('インスタンスリクエスト成功インターセプト')
            return config
        },
        onRejected(error) {
            console.log('インスタンスリクエスト失敗インターセプト')
            return error
        },
    },
    responseInterceptor: {
        onFulfilled(value) {
            console.log('インスタンスレスポンス成功インターセプト')
            return value.data
        },
        onRejected(error) {
            console.log('インスタンスレスポンス失敗インターセプト')
            return error
        },
    },
})

type IData = any[]

const getBanner = () => {
    instance
        .get<IResponse<IData>>({
            url: '/banner',
            requestInterceptor: {
                onFulfilled(config) {
                    console.log('インターフェースリクエスト成功インターセプト')
                    return config
                },
                onRejected(err) {
                    console.log('インターフェースリクエスト失敗インターセプト')
                    return err
                },
            },
            responseInterceptor: {
                onFulfilled(data) {
                    console.log('インターフェースレスポンス成功インターセプト')
                    return data
                },
                onRejected(err) {
                    console.log('インターフェースレスポンス失敗インターセプト')
                    return err
                },
            },
        })
        .then((res) => {
            console.log(res)
        })
}
getBanner()
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。