Skip to main content
Version: Next

RESTful API Integration

Table of Contents​

  1. Introduction
  2. Project Structure Overview
  3. Core Request Encapsulation Module
  4. API Interface Organization Architecture
  5. Authentication and Security Mechanism
  6. Environment Configuration and Proxy
  7. Error Handling and Unified Response
  8. Caching Strategy and Performance Optimization
  9. Pagination and Parameter Processing
  10. Mock Data and Development Debugging
  11. Practical Usage Examples
  12. Best Practices and Extension Guide

Introduction​

The lmes-web-base project adopts a RESTful API integration scheme based on axios, providing a complete frontend and backend communication solution. Through a well-designed request encapsulation layer, unified error handling mechanism, intelligent caching strategy, and flexible environment configuration, the system provides stable and reliable API communication capabilities for frontend applications.

Project Structure Overview​

Diagram sources

Core Request Encapsulation Module​

request.ts Module Architecture​

request.ts is the core module of the entire API integration, deeply encapsulated based on axios, providing complete request lifecycle management.

Diagram sources

Request Interceptor Functions​

The request interceptor is responsible for preprocessing before the request is sent:

  1. Auth Token Injection: Automatically get Token from Session storage and add to Authorization header
  2. Default Header Setting: Merge default Content-Type and other business-related headers
  3. XML String Processing: Identify and correctly handle XML formatted string data
  4. Silent Mode Support: Decide whether to display loading animation based on configuration

Response Interceptor Functions​

The response interceptor processes data returned by the server:

  1. Data Extraction: Automatically extract response.data part
  2. Error Proxy Detection: Identify and handle interfaces not found by proxy
  3. Blob Type Processing: Special handling for file download scenarios
  4. Status Code Mapping: Map HTTP status codes to user-friendly error messages

Section sources

API Interface Organization Architecture​

Project-level API Organization​

The project adopts a modular API organization method, with independent API files for each business domain:

Diagram sources

API Method Type Support​

The system supports complete RESTful methods:

  • GET: Used for data query and resource retrieval
  • POST: Used for data creation and complex query
  • PUT: Used for resource update
  • DELETE: Used for resource deletion

Section sources

Authentication and Security Mechanism​

Token Injection Mechanism​

The system implements an automated Token management mechanism:

// Automatically get Token from Session storage
const token = Session.get('Token')

// Dynamically calculate Authorization header
get Authorization() {
return token ? `Bearer ${token}` : undefined
}

Header Security Policy​

  1. Content-Type Enforcement: Ensure all requests use application/json format
  2. Project Identifier: Automatically inject X-Project header to identify current project
  3. Client Identifier: Add X-Client-Id to support multi-client identification
  4. Language Environment: Dynamically set Accept-Language header

Re-login Mechanism​

When encountering 401 or 403 status codes, the system will trigger a re-login popup:

Diagram sources

Section sources

Environment Configuration and Proxy​

Environment Variable Driven baseURL Switching​

The system supports configuring baseURL in multiple ways:

// Prioritize getting from URL parameters
let baseURL = params.get('baseURL') || ''

// Support overriding via baseURL parameter
console.info('[baseURL]', baseURL)

Development Environment Proxy Configuration​

The development environment configures a complete proxy system via Vite:

Diagram sources

Path Alias Configuration​

The system configures multiple path aliases to simplify imports:

  • @ → ./src
  • components → ./src/components
  • sdk → ./src/cms/sdk.es.js

Section sources

Error Handling and Unified Response​

Unified Error Handling Mechanism​

The system implements multi-level error handling:

Diagram sources

Error Message Processing​

The system supports multiple error message sources:

  1. Response Body Error: Prioritize getting from data.msg, data.message, etc.
  2. Status Text: Use statusText as backup
  3. Default Message: Use "Request Error" as final backup

Loading Animation Management​

The system implements intelligent loading animation management:

// Request counter
let reqNum: number = 0

// Show loading animation
const setLoading = (silent: boolean) => {
if (silent) return

reqNum++
if (reqNum === 1) {
loadingInstance = ElLoading.service(loadingOptions)
}
}

// Close loading animation
const closeLoading = (silent: boolean) => {
if (silent) return
reqNum--
if (reqNum <= 0) {
reqNum = 0
loadingInstance && loadingInstance.close()
}
}

Section sources

Caching Strategy and Performance Optimization​

Memory Caching Mechanism​

The system implements a memory-based caching strategy:

Diagram sources

Variable Query Caching​

The system implements a 5-minute caching mechanism for variable queries:

private async queryVariable(next: () => void) {
const size = this.getState(Base.MAP_KEY)?.size
const t = this.getState(Base.CACHE_KEY) || Date.now()

// Return directly if within cache validity period
if (size > 0 && Date.now() - t < Base.CACHE_TIME) {
return next && next()
}

// Cache expired, initiate new request
try {
const vars = await request.get('/api/v1/variable/query')
const varMap = this.transformArrayToMap(vars.result)
this.setState(Base.CACHE_KEY, Date.now())
this.setState(Base.MAP_KEY, varMap)
next && next()
} catch (error) {
console.error(error, 'Variable query interface error, pause request')
}
}

Throttling and Debouncing Mechanism​

The system provides high-performance throttling and debouncing tools:

export const genSetInterval = (fn: () => void, time: number = 33): Timer => {
let timerId: number | null = null
let lastTime = performance.now()

const loop = (currentTime: number) => {
const deltaTime = currentTime - lastTime

if (deltaTime >= time) {
fn()
lastTime = currentTime - (deltaTime % time) // Keep remaining time, reduce drift
}

timerId = requestAnimationFrame(loop)
}

return {
start() {
if (timerId === null) {
lastTime = performance.now()
timerId = requestAnimationFrame(loop)
}
},
clear() {
if (timerId !== null) {
cancelAnimationFrame(timerId)
timerId = null
}
},
}
}

Section sources

Pagination and Parameter Processing​

Pagination Parameter Standardization​

The system implements a unified pagination parameter processing mechanism:

Diagram sources

Pagination Component Implementation​

The system provides two pagination components:

  1. BaseTable Pagination: Integrated in the table component
  2. MyPages Component: Independent pagination control
// Get pagination parameters
const getPaginationParams = () => {
return {
pageNum: pageNum.value,
pageSize: params.value.MaxResultCount,
totalCount: totalCount.value,
}
}

// Table scroll to specified row
const scrollToRow = async ({ row, skip }: any) => {
if (skip) {
if (totalCount.value > dataSource.value.length) {
// Jump to last page
pageNum.value = Math.ceil(totalCount.value / params.value.MaxResultCount)
params.value.SkipCount = (pageNum.value - 1) * params.value.MaxResultCount
}
await getTableList()
skipRow(dataSource.value[dataSource.value.length - 1])
} else {
skipRow(row)
}
}

Parameter Serialization Processing​

The system automatically handles parameter serialization for various types:

// Automatic JSON serialization
if (
typeof config.data !== 'object' &&
!isXMLString &&
config.headers['Content-Type'].match(/application\/json/i)
) {
config.data = JSON.stringify(config.data)
}

Section sources

Mock Data and Development Debugging​

Mock System Architecture​

The system provides complete Mock data support:

Diagram sources

Development Environment Debugging Support​

The system supports multiple development debugging modes:

  1. Static File Mock: Provide static data via mock.json
  2. Dynamic Mock: Provide dynamic behavior via index.js
  3. Multi-language Mock: Support localization testing
  4. Component Mock: Support component-level simulation

Interface Integration Mechanism​

The development environment provides complete interface integration support:

// API route switching between development and production environments
return import.meta.env.PROD
? sdk.request({ url, method, params: { ...provider } })
: request({ url, method, params: { ...provider } })

Section sources

Actual Usage Examples​

Basic API Call​

// Get project configuration
export const getProjectConfig = (name: string) => {
return request.get(`/projectApi/env?name=${name}`)
}

// Create component
export const createWidget = (data) => {
return request.post(`/projectApi/create`, data)
}

Advanced API Call​

// Product list query (with condition filtering)
function getproductList(data: any, hasFormula: boolean = true) {
const url = `api/v1/messuite/query/product?filter=${data.filter}&hasFormula=${hasFormula}`
const method = 'get'
return request({ url, method })
}

// Work section list query (with capability type filtering)
function getWorksectionList(data: any) {
const url = `api/v1/messuite/query/worksection?filter=${data.filter}&abilityType=${data.abilityType}&includeDetails=${data.includeDetails}`
const method = 'get'
return request({ url, method })
}

Error Handling Example​

// Request with silent mode
try {
const result = await request.get('/api/v1/data', {
silent: true, // Do not display loading animation
unLogError: true, // Do not display error prompt
})
} catch (error) {
console.error('API call failed:', error)
}

File Upload Example​

// File upload (supports FormData)
export const postImport = (file: FormData) => {
return request({
url: `/api/v1/zc/productsop/uploadsop`,
method: 'post',
contentType: 'multipart/form-data',
headers: { accept: '*/*' },
data: file,
})
}

Section sources

Best Practices and Extension Guide​

Extending Custom Headers​

// Add custom headers in request config
const customRequest = async (url: string, data?: any) => {
return request({
url,
method: 'post',
headers: {
'X-Custom-Header': 'custom-value',
'X-Additional-Info': 'additional-info',
},
data,
})
}

Adapting Pagination Parameter Format​

// Unified pagination parameter processing
const getPagedParams = (pageNum: number, pageSize: number) => {
return {
SkipCount: (pageNum - 1) * pageSize,
MaxResultCount: pageSize,
}
}

// Usage example
const fetchData = async (pageNum: number, pageSize: number) => {
const params = getPagedParams(pageNum, pageSize)
return request.get('/api/v1/data/list', { params })
}

Interface Version Control​

// Versioned API call
const apiVersion = 'v1'

const getVersionedRequest = (endpoint: string) => {
return request.get(`/api/${apiVersion}/${endpoint}`)
}

// Usage example
const getData = async () => {
return getVersionedRequest('data')
}

High Frequency Request Throttling​

// Throttle wrapper
const createThrottledRequest = (fn: Function, delay: number = 300) => {
let lastCall = 0
return async (...args: any[]) => {
const now = Date.now()
if (now - lastCall < delay) {
return Promise.reject(new Error('Request too frequent'))
}
lastCall = now
return fn(...args)
}
}

// Usage example
const throttledGetData = createThrottledRequest(getData)

Extending Error Handling​

// Custom error processor
const handleError = (error: any) => {
switch (error.status) {
case 400:
ElMessage.error('Request parameter error')
break
case 401:
ElMessage.error('Please login first')
break
case 403:
ElMessage.error('Insufficient permission')
break
case 404:
ElMessage.error('Resource not found')
break
default:
ElMessage.error('Network error, please try again later')
}
}

Performance Monitoring Integration​

// Request performance monitoring
const monitoredRequest = async (config: any) => {
const startTime = performance.now()
try {
const result = await request(config)
const endTime = performance.now()
console.log(`API ${config.url} took: ${endTime - startTime}ms`)
return result
} catch (error) {
const endTime = performance.now()
console.error(`API ${config.url} failed, took: ${endTime - startTime}ms`)
throw error
}
}

This document comprehensively covers all key aspects of RESTful API integration in the lmes-web-base project, from basic request encapsulation to advanced performance optimization, providing complete technical reference and best practice guidance for developers. Through reasonable architecture design and rich functional features, the system can meet various needs of modern Web applications for API integration.