Read a lot of people’s encapsulating Axios tutorials online, but there are more or less inappropriate points, here are my best practices for you.
The interceptor does not return data, but still returns an AxiosResponse object
The articles on the Internet ask you to use interceptors to directly return data, which is actually very inappropriate, so that you will be difficult to expand the function.
Not recommended
import Axios from 'axios'
const client = Axios.create({
// Your configuration
})
client.interceptors.response.use(response= > {
// The Internet always asks you to return the data directly
// This makes it difficult to support subsequent functions
return response.data
})
export default client
Copy the code
Recommended practices
It is recommended to use functions instead of interceptors
import Axios, { AxiosRequestConfig } from 'axios'
const client = Axios.create({
// Your configuration
})
export async function request(url: string, config? : AxiosRequestConfig) {
const response = awaitclient.request({ url, ... config })const result = response.data
// Your business judgment logic
return result
}
export default client
Copy the code
At this point some people may say too much trouble, please wait a moment, continue to read.
Add an extension to your request
A lot of times, our development process looks like this:
Send request => get data => Render contentCopy the code
Unfortunately, this is an ideal situation, and there are special cases where you need to handle exceptions or additional support, such as:
- When a request fails, you want to automatically retry the request for more than three times
- In paging data, the automatic interruption of the previous request when a new one is made
- When a third party provides a JSONP interface and you can only use static pages (PS: Axios does not support JSONP)
- More and more
You can only write code support silently when sending the above scenarios, but if you don’t intercept the Axios response, you can use the solution provided by the open source community.
Support request retry
Install AXIos-Retry to enable automatic retry in your AXIos
import Axios, { AxiosRequestConfig } from 'axios'
import axiosRetry from 'axios-retry'
const client = Axios.create({
// Your configuration
})
// Install the Retry plug-in
// When a request fails, the request is automatically rerequested
axiosRetry(client, { retries: 3 })
export async function request(url: string, config? : AxiosRequestConfig) {
const response = awaitclient.request({ url, ... config })const result = response.data
// Your business judgment logic
return result
}
// Only after three failures do you really fail
const data = request('http://example.com/test')
Copy the code
The PS: AXIos-Retry plug-in supports configuring a single request
Support for JSONP requests
Install Axios-jSONp to make your AXIos support JSONP functionality.
import Axios, { AxiosRequestConfig } from 'axios'
import jsonpAdapter from 'axios-jsonp'
const client = Axios.create({
// Your configuration
})
export async function request(url: string, config? : AxiosRequestConfig) {
const response = awaitclient.request({ url, ... config })const result = response.data
// Your business judgment logic
return result
}
export function jsonp(url: string, config? : AxiosRequestConfig) {
returnrequest(url, { ... config,adapter: jsonpAdapter })
}
// You can now send jSONP requests
const data = jsonp('http://example.com/test-jsonp')
Copy the code
Supports URI version control
Anyone with experience in Web API development will encounter a problem: if there is a major change to the API, how do you release the new API while keeping the old version available?
This situation is not uncommon in server-side development scenarios, especially for public apis such as douban API (invalid).
Currently, there are three main types of version control supported:
type | describe |
---|---|
URI Versioning | Version will be passed in the URI of the request (default) |
Header Versioning | The custom request header specifies the version |
Media Type Versioning | The Accept request header specifies the version |
URI version control refers to the version passed in the request URI, such as https://example.com/v1/route and https://example.com/v2/route.
import Axios, { AxiosRequestConfig } from 'axios'
const client = Axios.create({
// Your configuration
})
client.interceptors.request.use(config= > {
// The simplest solution
config.url = config.url.replace('{version}'.'v1')
return config
})
// GET /api/v1/users
request('/api/{version}/users')
Copy the code
Header and Media Type modes can be implemented by referring to the following article
- Implement the Web API Versioning function
- nest versioning
Keep requests unique
In a background table page that supports page-turning, a user clicks the page-turning button and requests a waiting response. However, the user clicks search and needs to retrieve the data again.
- Page turn request first return, search data return, data display normal
- Search data is returned first, and page data is returned again. Data is displayed abnormally (usually in load balancing scenarios)
To do this, you want to be able to cancel the last request automatically, so you look at Axios’ cancel request, but you need it in a lot of places, so you can encapsulate it as a separate function.
import Axios from 'axios'
const CancelToken = Axios.CancelToken
export function withCancelToken(fetcher) {
let abort
function send(data, config) {
cancel() // Cancel
const cancelToken = new CancelToken(cancel= > (abort = cancel))
returnfetcher(data, { ... config, cancelToken }) }function cancel(message = 'abort') {
if (abort) {
abort(message)
abort = null}}return [send, cancel]
}
Copy the code
use
function getUser(id: string, config? : AxiosRequestConfig) {
return request(`api/user/${id}`, config)
}
// Wrap the request function
const [fetchUser, abortRequest] = withCancelToken(getUser)
// Send the request
// If the last request does not come back, it will be automatically cancelled
fetchUser('1000')
// Usually no active invocation is required
// But can be called during the component destruction lifecycle
abortRequest()
Copy the code
This does not need to automatically cancel the time, directly use the original function can, also will not affect the use of the original function
After the language
There’s a lot more that Axios encapsulation can do, such as global error handling (which doesn’t affect normal requests), and encapsulation shouldn’t just use interceptors to return data directly.
In addition, request modules should be kept separate. It is recommended to extend AxiosRequestConfig or make a separate function available for external calls to make it a separate HTTP module.