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()