http-data-request
A flexible network data request library based on axios with additional features
Repository status
Detailed changes for each release are documented in Changelog
Features
- Automatically save and apply authorization tokens
- Unified handling of exception information
- Customizable status code
- Customizable authorization data node
- Provides quick access functions for each request method
- Provides a function to cancel all current requests
Design Background
http-data-request
is suitable for scenarios where a custom encoding system is applied for web and server interaction applications, rather than directly using the native HTTP status code scheme
Business Data Format
The server responds to system business requests with HTTP 200 status, and the response data format is as follows:
{
// Business status code
"code": 0,
// Business exception information, only outputs "ok" in non-exceptional cases
"msg": "ok",
// Business data
"data": {}
}
The business status code code
usually has the following situations:
0
Request successful10
Access token invalid11
Refresh token invalid- Other business exceptions
Authentication Mode
The plugin provides two authentication modes, the difference between the two lies in how to handle the expiration of the authentication token
Successful Authentication Process
In the process, both store the token in local storage
and carry the token to make requests
are actions automatically handled by the plugin
Failed Authentication Process
Dual Token Mode
The application access token is short-term, and the refresh token is long-term.
- Carry access token to execute data request
- Respond with access token invalid status
{ code: 10, ... }
- http-data-request automatically uses the refresh token to send a request to refresh the access token
- If the response is successful, update the token-related information and re-initiate the data request
- If the response fails, it is considered that the user's authentication has expired and needs to log in again
{ code: 11, ... }
Single Token Mode
The application access token is long-term
- Carry access token to execute data request
- Respond with refresh token invalid status
{ code: 11, ... }
- If it fails, it is considered that the user's authentication has expired and needs to log in again
Installation
Install the http-data-request
component into your project
npm i http-data-request
yarn add http-data-request
pnpm add http-data-request
Add a file in the project, such as /src/config/http/index.js
, to set the global configuration of http-data-request and export various functional functions
import { useHttpDataRequest } from 'http-data-request'
import type { HttpDataRequestOptions } from 'http-data-request'
const options: HttpDataRequestOptions = {
baseUrl: 'https://example.com/api',
}
export const {
http, get, post, put, patch, del, cancel
} = useHttpDataRequest(options)
In the Vite configuration file vite.config.js
, set an alias for the project installation module directory for http
import { fileURLToPath, URL } from 'node:url'
import { resolve } from 'path'
import { defineConfig } from 'vite'
export default defineConfig({
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
'@api': fileURLToPath(new URL('./src/api', import.meta.url)),
'@http': fileURLToPath(new URL('./src/config/http', import.meta.url))
}
},
...
})
After applying the above configuration, in any position of the project, you can directly use the @http
aliases to use HTTP related functions
Basic Setup
Quick Functions
In the function set created by useHttpDataRequest
, the http
function is the core function for data requests, while get, post, put, patch, and del are quick functions for each request method
get('/user/1')
// Equivalent to
http('/user/1', undefined, { method: 'GET' })
The default request method for http
is POST
URL
If the provided URL is a relative path, it will be automatically concatenated with baseUrl
const options: HttpDataRequestOptions = {
baseUrl: 'https://example.com/api',
}
get('/user/1')
In this case, the actual request is to https://example.com/api/user/1
.
get('https://other-example.com/api/user/1')
If the URL starts with http/https
, it will directly use that address without concatenating baseUrl
This setup provides the convenience of quickly applying the base address within the system while retaining the flexibility to directly access other website addresses
Mismatched response format
Use http-data-request
to request data successfully. The response format is as follows
interface HttpDataRequestBody{
code: number
msg: string
data: any
}
If the response data format does not match HttpDataRequestBody
, the data will be returned directly, but at the same time, global exception handling will not take effect in the current request
Examples for apply
Project API Definition
// src/api/user.js
import { get, post } from '@http'
export function getUser(userId) {
return get(`/user/${userId}`)
}
Used in Components/Pages
<template>
<div>
<div>
User name: {{ user.name }}
</div>
<div>
User age: {{ user.age }}
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { getUser } from '@api/user'
const user = ref({})
getUser(10).then(data => { user.value = data })
</script>
Cancel Request
Cancel all currently executing requests
<template>
<div>
<div>
...order form
</div>
<button
type="button"
@click="save"
>Save order</button>
<!--
Clicking before the data is saved successfully
will cancel the data request
-->
<button
type="button"
@click="cancel"
>Cancel</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { DialogMessageSuccess } from 'v-dialogs'
import { cancel } from '@http'
import { saveOrder } from '@api/order'
function save() {
saveOrder({ ...formData }).then(() => {
DialogMessageSuccess('Order saved successfully')
})
}
</script>
Global Configuration
Here, the v-dialogs component is used as an example to display exception information content in the dialog
import {
useHttpDataRequest,
EXCEPTION_BUSINESS,
EXCEPTION_AUTH_INVALID
} from 'http-data-request'
import type { HttpDataRequestOptions } from 'http-data-request'
import { DialogMessageError, DialogAlertError } from 'v-dialogs'
import { logout } from './auth'
const options: HttpDataRequestOptions = {
baseUrl: 'https://example.com/api',
// global exception handle
exception (message, type) {
// display business exceptions message
if (type === EXCEPTION_BUSINESS) {
DialogMessageError(message)
return
}
// display rest of other exceptions message
DialogAlertError(message)
// some action for user authorization expired
if (type === EXCEPTION_AUTH_INVALID) {
// cancel all current request when
cancel()
// logout and redirect to login page
logout()
}
}
}
export const {
http, get, post, put, patch, del, cancel
} = useHttpDataRequest(options)
The above code is a typical application of global exception handling in the project, which has three parts of processing content
- Silently display business exception information
- Modal prompts other exception information, which requires user confirmation before continuing, such as system underlying exceptions, network exceptions, identity authentication failure, etc.
- When the identity token expires, cancel all current requests and log out
After setting up global exception handling, various types of exception information will be automatically displayed, so there is no need to handle exception information in the business code, just focus on processing business logic
Applying environment variables
The baseUrl
option specifies the base URL prefix for network requests. In actual project applications, different addresses need to be set for different working environments.
Take the vite
tool chain as an example, create the following three .env
environment configuration files in the project
# .env.development
VITE_BASE_URL=https://exapmle-dev.com/api
# .env.alpha
VITE_BASE_URL=https://exapmle-test.com/api
# .evn.production
VITE_BASE_URL=https://exapmle.com/api
After setting the environment variable configuration, access the variable content through import.meta.env.VITE_SOME_KEY
const options: HttpDataRequestOptions = {
baseUrl: import.meta.env.VITE_BASE_URL
}
In this way, when developing or building in different environments, the basic network addresses specified by different environments will be automatically applied
Request header authorization token
After successful login, subsequent data requests will add an authorization token to the request header. The following fields will be added by default
{
'Authorization': 'Bearer access-token-value'
}
Custom property names and settings without the Bearer
prefix
const options: HttpDataRequestOptions = {
tokenPrefix: false,
keys: {
header: 'x-http-request-access-token'
}
}
Applying this setting, the token attribute and value carried in the request header are as follows
{
'x-http-request-access-token': 'access-token-value'
}
Response status code
Assume that the status code scheme of the server response is as follows
// success
{ "code": 1000, "msg": "ok", "data": { ... } }
// access token invalid
{ "code": 1100, "msg": "access token invalid", "data": {} }
// refresh token invalid
{ "code": 1200, "msg": "refresh token invalid", "data": {} }
According to the status code of the server response, set the custom status code item in the statuses
option as follows
const options: HttpDataRequestOptions = {
baseUrl: 'https://example.com/api',
statuses: {
success: 1000,
invalidAccessToken: 1100,
invalidRefreshToken: 1200
}
}
In this way, http-data-request corresponds to the various status codes of the server response.
Authorization data node
http-data-request will automatically grab the authorization token and save the data to LocalStorage
. The default data format matched by the plugin is as follows
{
access: {
accessToken: 'access-token-value',
refreshToken: 'refresh-token-value',
expiresIn: 10086
}
}
When the plug-in processes the data request and returns the result, it will always detect whether there is an access
data node, and automatically store or replace it if it exists. This mechanism does not require manual processing of the operation of saving token information to local storage, and unifies the location and behavior of local storage of token information
This mechanism can also be used to implement the function of automatic login
const options: HttpDataRequestOptions = {
keys: {
dataSet: 'accessData',
accessToken: 'accessTokenKey',
refreshToken: 'refreshTokenKey',
expiresIn: 'expiresOn'
}
}
This custom node setting matches the response data format of the following server
{
accessData: {
accessTokenKey: 'access-token-value',
refreshTokenKey: 'refresh-token-value',
expiresOn: 10086
}
}
When the access token expires, the plugin will automatically initiate a request to refresh the token (the location of the request is specified by the refreshUrl
option). The data body of the request is as follows
{
refreshToken: 'refresh-token-value'
}
If you need to customize the field name of the request body, you can set it through the keys.paramRefreshToken
option
const options: HttpDataRequestOptions = {
keys: {
paramRefreshToken: 'refreshTokenValue'
}
}
After applying this setting, the request body sent when refreshing the access token is as follows
{
refreshTokenValue: 'refresh-token-value'
}
API
http-data-request setup function for project
function useHttpDataRequest(
options: HttpDataRequestOptions
): HttpDataRequestMethods
useHttpDataRequest
input parameters HttpDataRequestOptions
type description
interface HttpDataRequestOptions {
/**
* Plugin language
* @default `en`
*/
language?: LanguageType
/**
* Base url path
* @default `/`
*/
baseUrl: string
/**
* The url used to refresh new access token
* @default `/auth/refresh-token`
*/
refreshUrl?: string
/**
* @default 0
*/
expiresIn?: number
/**
* Specifies the number of milliseconds before the request times out
* @default 10000
*/
timeout?: number
/**
* Customize the key name of the data node
*/
keys?: {
/**
* Access data node name
* @default `access`
*/
dataSet?: string
/**
* Access token property name
* @default `accessToken`
*/
accessToken?: string
/**
* Refresh token property name
* @default `refreshToken`
*/
refreshToken?: string
/**
* Token expires in property name
* @default `expiresIn`
*/
expiresIn?: string
/**
* The property name in the request body to pass refresh token
* @default `refreshToken`
*/
paramRefreshToken?: string
/**
* The property name of the request headers to pass access token
* @default `Authorization`
*/
header?: string
}
/**
* Customize the status code of the response
*/
statuses?: {
/**
* Success status code
* @default 0
*/
success?: number
/**
* Access token invalid status code
* @default 10
*/
invalidAccessToken?: number
/**
* Refresh token invalid status code
* @default 11
*/
invalidRefreshToken?: number
}
/**
* Request exception handle
*/
exception?: (message: string, type: EXCEPTION_TYPE) => void
}
type EXCEPTION_TYPE =
| 'exception-business'
| 'exception-auth-invalid'
| 'exception-system'
The type description of the function set HttpDataRequestMethods
created after executing useHttpDataRequest
interface HttpDataRequestMethods {
/**
* Core function of HTTP data request
*/
http: typeof HttpDataRequest
/**
* Quick functions for get, post, put, patch, and delete request methods
*/
get: typeof HttpDataRequest
post: typeof HttpDataRequest
put: typeof HttpDataRequest
patch: typeof HttpDataRequest
del: typeof HttpDataRequest
/**
* Cancel all current requests
*/
cancel: () => void
}
function HttpDataRequest(
// Data request URL
url: string,
// Request data
data: any,
// Native axios request configuration parameters
options: AxiosRequestConfig
): Promise<any>
For the complete axios config, please visit axios-request-config