wxess-axios v1.0.8
wxess-axios
this is a request library based on axios secondary encapsulation
Don't know axios?
please check the official documents of axios => click me
Packaging Characteristics
- Features
- Installing
- Basic usage
- Create instance configuration
- Request apis configuration
- Public configuration
- Define interceptors
- How to support typescript
- Business requirements
- How to organize your code
- License
Features
- Support most features of axios
- Quickly realize basic requirements by configuration
- Better support for typescript
- More suitable for business projects
Installing
Using npm:
$ npm install wxess-axios -S
Basic usage
// Create an axios instance
import { createAxios } from 'wxess-axios';
const axios = createAxios({
// host api
baseURL: 'http://xxx',
headers: {
'content-type': 'application/json'
}
});
// Request API definition
const handleLogin = (data) => {
return axios.createRequest({
url: '/api/login',
method: 'post',
data
});
};
// Using APIs
const params = {
username: 'xxx',
password: 'xxx'
};
const clickHandle = async () => {
if(params.username !== '' && params.password !== '') {
const result = await handleLogin(params);
console.log(result); // response result
}
};
Create instance configuration
Instance options will inherit the Public configuration
const axios = createAxios({
// Host api (Required)
baseURL: string;
// Run in build environment? (Optional)
// If the value is true, some internal warnings will be ignored
// The default value is false
isPro: boolean;
// You can continue to add public configuration or Axios configuration below
...others
});
Request apis configuration
Request apis configuration also inherits the Public configuration
const promise = axios.createRequest({
// Whether to ignore instance interceptors and request API interceptors
// The default value is false
isIgnoreInterceptor: boolean;
// You can continue to add public configuration or Axios configuration below
...others
});
Public configuration
Public configuration will eventually inherit Axios configuration
{
// Can I cancel the request manually?
// The default value is false
isCancelRequest: boolean;
// Whether to convert form data into URL parameters when submitting it in JSON
// Note: the content type of the request must be 'post' or 'put'
// The default value is true
isToURL: boolean;
// How the interceptor works?
// The default value is `auto`
pattern: 'cover' | 'no-repeat' | 'add' | 'auto';
// Specify the keys of the interceptor to be used
interceptors: {
request?: string[];
response?: string[];
errorRequest?: string[];
errorResponse?: string[];
common?: string[];
}
}
Define interceptors
There are five types, namely: request
, response
, errorRequest
, errorResponse
, common
The following example will introduce the request
interceptor
// define
const reqInter = {
carryToken: (params) => {
const { requestData, isPass, config, ...others } = params;
/* When 'isPass' is' true', the returned parameters
will be passed to the next interceptor */
/* otherwise the interceptor will be aborted, Then return
'responsedata' to Axios for internal processing */
return {
// Axios request configuration
requestData,
// Continue to call the interceptor?
isPass,
// Combined configuration of instance configuration and
// request API configuration
config,
// Custom passed parameters
...others
}
},
openLoading: (params) => {
return params;
}
};
// register or remove
axios.registerInterceptors('request', reqInter);
axios.unRegisterIntercetors('request', ['carryToken']);
// First usage(low priority)
const axios = createAxios({
interceptors: {
request: ['carryToken']
}
});
// Second usage (higher priority)
const promise = createRequest({
interceptors: {
request: ['openLoading']
}
});
NOTE: The pattern
option of public configuration will affect the merging rules of interceptors
How to support typescript
// Get type prompt when using request API
// Generally, the client and server will agree on this format
type ResponseResult = {
msg: string;
status: number;
data: {
response: void; // Special attention should be paid here
tips: string;
code: number;
...
}
};
// Get type prompt when configuring interceptor
import { ReqInterceptorParams } from 'wxess-axios';
const reqInter = {
handleRequest({ requestData, isPass, config }: ReqInterceptorParams) {
// Processing business
return {
requestData, isPass, config
}
}
};
type InterceptorKeys = {
request: (keyof typeof reqInter)[],
response: [],
errorRequest: [],
errorResponse: []
}
// Injection InterceptorKeys and ResponseResult
const axios = createAxios<ResponseResult, InterceptorKeys>({
baseURL: 'xxxx'
});
// Use cases
interface LoginParams = {
username: string;
password: string;
}
const handleLogin = async (data: LoginParams) => {
// The type here will replace the 'void' in the 'responseResult' type`
type LoginResult = {
uid: string;
username: string;
};
return axios.createRequest<LoginResult>({
url: '/api/login',
method: 'post',
data
});
}
const result = await handleLogin({
username: 'xxx',
password: 'xxx'
});
// The result here has the type prompt
console.log(result);
NOTE: The response interceptor must be used to return the specified response type
You can also customize the processing of response data at the front end
Of course, if the client
and server
can directly return the specified type of data, there is no need to process it
import { ResInterceptorParams } from 'wxess-axios';
const resInter = {
// The following case uses the server built by koa router
handleResponseData({ responseData, ...others }: ResInterceptorParams) {
const { status, statusText, data } = responseData;
return {
// The data here will be passed to the interceptor later,
// and finally returned to the business API
responseData: {
msg: statusText,
status,
data
},
...others
}
}
};
// Don't forget to register
axios.registerInterceptors('response', ['handleResponseData']);
// Don't forget to configure
const axios = createAxios<ResponseResult, InterceptorKeys>({
baseURL: 'xxxx',
interceptors: {
response: ['handleResponseData']
}
});
Business requirements
Here we will introduce some common business requirements
Carry token
import { createAxios, ReqInterceptorParams } from 'wxess-axios';
// define
const reqInter = {
carryToken: ({ config, isPass, ...others }: ReqInterceptorParams) => {
const token = localStorage.getItem('pc-user-token');
if (token) {
config.headers!.Authorization = token;
}
return {
config,
...others
}
}
};
// to configure
const axios = createAxios({
interceptors: {
request: ['carryToken']
}
});
// register
axios.registerInterceptors('request', ['carryToken']);
Global request animation
Here, take vue3 +element plus as an example
Define the display state of the animation
import { reactive, toRefs } from 'vue';
// Expose hook
export function useLoading() {
const status = reactive({
isLoading: false,
size: 0
});
return {
...toRefs(status),
setLoading: createStatus(status, 'isLoading'),
addSize: createStatusByAdd(status, 'size')
};
}
// Modify the display status
function createStatus(status, key) {
return (value) => {
return status[key] = value;
};
}
// Record the number of multiple concurrent requests
function createStatusByAdd(status, key) {
return (value) => {
return status[key] += value;
};
}
UI control of loading animation
import { watch } from 'vue';
import { ElLoading } from 'element-plus';
import { useLoading } from 'xxx';
const { isLoading, setLoading, addSize } = useLoading();
// `element-plus` loading instance
let loadingInstance = null;
// Delay execution timer
let loaderTimer = null;
watch(isLoading, (nValue) => {
if (nValue) {
// After the server returns the result within 300ms
// Global animation is not displayed
loaderTimer = setTimeout(() => {
loadingInstance = ElLoading.service({
lock: true,
text: 'loading...',
background: 'rgba(0, 0, 0, 0.6)',
});
}, 300);
} else {
if (loadingInstance) {
loadingInstance.close();
}
clearTimeout(loaderTimer);
}
});
// You can use this function in the interceptor to control
// the state of the loading animation
export function alterLoadingStatus(isRequest) {
if (addSize(0) === 0) {
setLoading(true);
}
isRequest ? addSize(1) : addSize(-1);
if (addSize(0) === 0) {
setLoading(false);
}
}
Associate the feature loaded with animation with the interceptor of axios
import { alterLoadingStatus } from 'xxx';
import { CommonInterceptorParams } from 'wxess-axios';
// Define common interceptor
const commonInter = {
loadingAnimation: (config: CommonInterceptorParams) => {
const { interType } = config;
if (interType === 'request') {
alterLoadingStatus(true);
} else {
alterLoadingStatus(false);
}
return config;
}
};
// to configure
const axios = createAxios({
interceptors: {
request: ['loadingAnimation']
}
});
// register
axios.registerInterceptors('common', commonInter);
NOTE: If other interceptors conflict with the key of the common
interceptor, the common
interceptor will be ignored
Processing error statusCode
import { AxiosErrorType, ResErrorInterceptorParams } from 'wxess-axios';
const resErrorInter = {
responseStatusCode({ error, ...others }: ResErrorInterceptorParams) {
let errorMsg = 'unknown error';
if (error) {
const { name, code, request, response } = error;
if (name === 'AxiosError') {
switch (code) {
// Client error
case AxiosErrorType.evreq:
// You can handle client errors here => Status code 4xx
break;
// Server error
case AxiosErrorType.ebres:
// You can handle server errors here => Status code 5xx
break;
// others
}
} else if (name === 'CanceledError') {
errorMsg = 'The request has been `cancelToken.cancel ` cancelled!'
}
error.message = errorMsg;
}
return {
error,
...others
}
}
};
Before creating a response error handler, you should specify which status codes will be processed by response
or errorResponse
interceptor
const axios = createAxios({
// default value
validateStatus(code) {
return code >= 200 && code < 300;
},
interceptors: {
errorResponse: ['responseStatusCode']
}
});
axios.registerInterceptors('errorResponse', resErrorInter);
Cancel request
const handleLogin = (data) => {
const handler = axios.createRequest({
url: '/api/login',
method: 'post',
data,
// This parameter must be specified to cancel the request
isCancelRequest: true
});
};
// Execute the cancellation request at the appropriate time
axios.cancelRequest('All requests on the instance have been canceled!');
How to organize your code
Will be available in the next version