Introducing @varlet/axle: A Progressive Request Utility Built on Axios
The article presents @varlet/axle, a progressive request utility that fully inherits Axios capabilities while adding unified request parameters, extensive configuration, built‑in interceptors, Vue composition‑API integration, and parallel request tools, offering developers a convenient library for handling HTTP calls.
Introducing @varlet/axle
@varlet/axle is a progressive request utility that fully inherits all abilities of axios and retains access to the original axios object without altering its behavior. It is packaged as an npm library for easy reuse across projects.
Design Principles
The library is designed to completely inherit axios's capabilities while preserving the ability to access the original axios instance, ensuring no breaking changes to existing axios behavior.
Overview
Built on axios, @varlet/axle provides a unified request API that does not disrupt axios's native features, simplifying request handling for developers.
Quick Start
Installation
# Install via npm, yarn, or pnpm
# npm
npm i @varlet/axle -S
# yarn
yarn add @varlet/axle
# pnpm
pnpm add @varlet/axleSending Requests
The Axle object normalizes request function parameters and extends them for various business needs. A simple example:
import { createAxle } from '@varlet/axle';
const axle = createAxle();
axle.get('/url', { current: 1, pageSize: 10 }, { headers: {} });
axle.post('/url', { name: 'Axle' }, { headers: {} });Configuration
Axle fully supports all axios configuration options. Example:
const axle = createAxle();
const { axios } = axle;
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['TOKEN'] = TOKEN;
axios.defaults.timeout = 2500;
// request interceptor
axios.interceptors.request.use(config => config, error => Promise.reject(error));
// response interceptor
axios.interceptors.response.use(response => response, error => Promise.reject(error));Axle & Axios Request Functions
Axle provides request functions that mirror axios, with additional shortcuts for different response types. Examples:
GET
JSON
// axios
axios.get('/url', { params: { id: 1 } });
// axle
axle.get('/url', { id: 1 });Blob
// axios
axios.get('/url', { params: { id: 1 }, responseType: 'blob' });
// axle
axle.getBlob('/url', { id: 1 });Text
// axios
axios.get('/url', { params: { id: 1 }, responseType: 'text' });
// axle
axle.getText('/url', { id: 1 });Document
// axios
axios.get('/url', { params: { id: 1 }, responseType: 'document' });
// axle
axle.getDocument('/url', { id: 1 });ArrayBuffer
// axios
axios.get('/url', { params: { id: 1 }, responseType: 'arraybuffer' });
// axle
axle.getArrayBuffer('/url', { id: 1 });Stream
// axios
axios.get('/url', { params: { id: 1 }, responseType: 'stream' });
// axle
axle.getStream('/url', { id: 1 });POST
JSON
// axios
axios.post('/url', { name: 'foo' });
// axle
axle.post('/url', { name: 'foo' });application/x-www-form-urlencoded
// axios
axios.post('/url', qs.stringify({ name: 'foo' }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });
// axle
axle.postUrlEncode('/url', { name: 'foo' });multipart/form-data
// axios
const formData = new FormData();
formData.append('name', 'foo');
formData.append('file', new File());
axios.post('/url', formData, { headers: { 'Content-Type': 'multipart/form-data' } });
// axle
axle.postMultipart('/url', { name: 'foo', file: new File() });Utility Functions
Browser Download
import { download } from '@varlet/axle';
download(await axle.getBlob('/url', { id: 1 }), 'filename');Header Operations
const headers = axle.getHeaders();
axle.setHeader('TOKEN', TOKEN);
axle.removeHeader('TOKEN');Built‑in Interceptors
Axle offers a set of ready‑made request and response interceptors compatible with both axle and axios. Example of using axios interceptors directly:
import { requestHeadersInterceptor, responseRetryInterceptor } from '@varlet/axle';
const headersInterceptor = requestHeadersInterceptor({
headers: () => ({ token: localStorage.getItem('token'), 'Axle-Custom-Header': 'Axle-Custom-Header' })
});
const retryInterceptor = responseRetryInterceptor({ count: 3 });
axios.interceptors.request.use(headersInterceptor.onFulfilled, headersInterceptor.onRejected, headersInterceptor.options);
axios.interceptors.response.use(retryInterceptor.onFulfilled, retryInterceptor.onRejected, retryInterceptor.options);Using the same interceptors with axle:
import { requestHeadersInterceptor, responseRetryInterceptor } from '@varlet/axle';
axle.useRequestInterceptor(requestHeadersInterceptor({
headers: () => ({ token: localStorage.getItem('token'), 'Axle-Custom-Header': 'Axle-Custom-Header' })
}));
axle.useResponseInterceptor(responseRetryInterceptor({ count: 3 }));Interceptor Options
Each built‑in interceptor supports include , exclude , and axiosInterceptorOptions for fine‑grained filtering based on method or glob patterns.
axle.useResponseInterceptor(
responseRetryInterceptor({
count: 3,
include: ['method:put', 'method:post'],
exclude: ['/system/**', '/user/addUser']
})
);Interceptor List
Name
Description
requestHeadersInterceptor
Custom request headers
requestMockInterceptor
Mock data
responseRetryInterceptor
Retry on request failure
responseStatusInterceptor
Intercept status codes
responseBlobInterceptor
Intercept blob responses
responseTimeoutInterceptor
Normalize timeout errors
Vue Composition API Integration
Axle provides a Vue composition‑API style hook that encapsulates loading state, error handling, progress tracking, data transformation, and lifecycle callbacks while inheriting all axios configurations.
<script setup>
import { createAxle } from '@varlet/axle';
import { createUseAxle } from '@varlet/axle/use';
const axle = createAxle();
const useAxle = createUseAxle({ axle, onTransform: response => response });
const [users, getUsers, { loading, error, uploadProgress, downloadProgress, abort }] = useAxle({
value: [],
method: 'get',
url: '/user',
immediate: true,
resetValue: true,
params: { current: 1, pageSize: 10 },
config: { headers: {} },
onBefore(refs) { console.log(refs); },
onSuccess() {},
onError() {},
onAfter() {}
});
</script>
<template>
<span>{{ users }}</span>
<span>{{ loading }}</span>
<span>{{ error }}</span>
<span>{{ uploadProgress }}</span>
<span>{{ downloadProgress }}</span>
<button @click="getUsers">发送请求</button>
<button @click="abort">中断请求</button>
</template>Parallel Request Utilities
Axle includes helpers for handling multiple concurrent requests, aggregating loading states and progress.
<script setup>
import { createAxle } from '@varlet/axle';
import { createUseAxle, useHasLoading, useAverageProgress, useValues } from '@varlet/axle/use';
const axle = createAxle();
const useAxle = createUseAxle({ axle });
const [users, getUsers, { loading: isUsersLoading, downloadProgress: usersDownloadProgress }] = useAxle({ value: [], method: 'get', url: '/user' });
const [roles, getRoles, { loading: isRolesLoading, downloadProgress: rolesDownloadProgress }] = useAxle({ value: [], method: 'get', url: '/role' });
const loading = useHasLoading(isUsersLoading, isRolesLoading);
const downloadProgress = useAverageProgress(usersDownloadProgress, rolesDownloadProgress);
const usersRoles = useValues(users, roles);
function sendAllRequest() {
getUsers();
getRoles();
}
</script>
<template>
<span>{{ usersRoles }}</span>
<span>{{ loading }}</span>
<span>{{ downloadProgress }}</span>
<button @click="sendAllRequest">发送全部请求</button>
</template>Conclusion
The author hopes that @varlet/axle will bring convenience to developers' daily work by providing a unified, extensible, and easy‑to‑use HTTP request solution.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.