Celeris Web Request Interceptor and Response Handling: Architecture and Implementation

Celeris Web implements a dual-interceptor pattern in HttpClient.ts that handles duplicate request cancellation, authentication token injection, and global response transformation through a customizable transform object defined in defaultTransform.ts.

Celeris Web is an open-source Vue 3 admin framework that provides a robust HTTP client built on top of Axios. The request interceptor and response handling system manages the complete lifecycle of API calls, from pre-flight configuration to post-response data transformation. This architecture ensures consistent request formatting, automatic pending request management, and centralized error handling across the application.

How the Request Interceptor Works in Celeris Web

The request interceptor is initialized within the HttpClient class constructor via setupInterceptors(). This method registers an Axios request interceptor that executes a defined pipeline before any request reaches the network.

Duplicate Request Cancellation

The first responsibility of the request interceptor is preventing redundant network calls. When requestOptions.shouldIgnoreAbortController is false, the interceptor registers the outgoing request with the AxiosCanceler utility using addPending(config). This creates a unique fingerprint for the request based on its method and URL, allowing identical concurrent requests to be automatically aborted. The implementation appears at [lines 71-84 of HttpClient.ts](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/HttpClient.ts#L71-L84).

Authentication and Header Injection

Following cancellation setup, the interceptor executes transform.requestInterceptors. In the default implementation, this function automatically injects the Authorization header with the bearer token when shouldSendTokenInHeader is enabled. The interceptor receives the full AxiosRequestConfig and the global options object, allowing modification of headers, URL parameters, or request payloads before transmission.

Request Error Handling

If an error occurs before the request is dispatched (e.g., during configuration serialization), the interceptor catches the failure and passes it to transform.requestInterceptorsError. This hook enables logging, analytics tracking, or fallback logic for configuration-level failures.

Response Handling and Data Transformation

The response interceptor, defined at [lines 92-107 of HttpClient.ts](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/HttpClient.ts#L92-L107), manages the post-flight phase of HTTP communication. It processes successful responses and errors through a standardized pipeline.

Pending Request Cleanup

Upon receiving any response, the interceptor immediately invokes AxiosCanceler.removePending(response.config). This removes the request from the internal pending map, preventing memory leaks and ensuring that subsequent identical requests are not incorrectly flagged as duplicates. This cleanup occurs before any data transformation to maintain state consistency.

Response Transformation Pipeline

Successful responses flow through transform.responseInterceptors, which can unwrap API envelopes, normalize status codes, or trigger global notifications. The transformed response is then passed to transform.afterResponse, which handles final data extraction. By default, this method returns the native response when shouldReturnNativeResponseHeaders is true, or extracts the data property from standard API responses.

Error Interception and Recovery

Failed responses (network errors, 4xx/5xx status codes) trigger transform.responseInterceptorsError. This handler receives both the error object and the Axios instance, enabling sophisticated recovery strategies such as token refresh, request retry, or redirect to authentication flows.

The Transform Object: Customization Layer

The transform object serves as the extensibility layer for both interceptors. Defined in [packages/web/request/src/options/transform/defaultTransform.ts](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/options/transform/defaultTransform.ts), it provides concrete implementations for the hooks referenced by HttpClient.

Default Transform Methods

  • beforeRequest: Executes before the request interceptor runs. Handles URL prefixing, timestamp injection for cache busting, and date formatting via formatRequestDate.
  • afterResponse: Processes the raw Axios response. Unwraps API envelopes, handles success messaging, and validates response structures.
  • requestInterceptors: Injects authentication tokens and custom headers during the request phase.
  • responseInterceptors: Pass-through by default, but available for global response mutation.

Extending Default Behavior

Developers can override specific methods while preserving default functionality through object spreading.

import { HttpClient } from '@celeris/web/request';
import { defaultTransform } from '@celeris/web/request/src/options/transform/defaultTransform';
import type { AxiosRequestConfig, AxiosResponse } from 'axios';

const customTransform = {
  ...defaultTransform,
  requestInterceptors: (config: AxiosRequestConfig) => {
    // Inject custom correlation ID for distributed tracing
    config.headers['X-Request-ID'] = crypto.randomUUID();
    return defaultTransform.requestInterceptors?.(config) ?? config;
  },
  responseInterceptorsError: (error, axiosInstance) => {
    // Global 401 handler
    if (error.response?.status === 401) {
      window.location.href = '/login';
    }
    return Promise.reject(error);
  },
};

const client = new HttpClient({
  baseURL: 'https://api.example.com',
  transform: customTransform,
});

Practical Implementation Examples

Basic API Client Configuration

import { HttpClient } from '@celeris/web/request';
import { createAxiosOptions } from '@celeris/web/request/src/axiosTransform';

// Initialize with default interceptors
const http = new HttpClient({
  baseURL: '/api',
  timeout: 10000,
  ...createAxiosOptions(),
});

// The request automatically passes through the interceptor pipeline
http.get('/users').then(data => console.log(data));

Conditional Token Injection

const selectiveTransform = {
  ...defaultTransform,
  requestInterceptors: (config: AxiosRequestConfig, options) => {
    // Skip authentication for public endpoints
    if (config.url?.startsWith('/public')) {
      return config;
    }
    // Apply default token injection for protected routes
    return defaultTransform.requestInterceptors!(config, options);
  },
};

Global Response Unwrapping

const apiTransform = {
  ...defaultTransform,
  afterResponse: (response: AxiosResponse) => {
    const apiData = response.data;
    // Standard API envelope: { code: 0, data: T, message: string }
    if (apiData.code !== 0) {
      throw new Error(apiData.message);
    }
    return apiData.data;
  },
};

Summary

  • Request Interceptor: Located in HttpClient.ts, manages duplicate request cancellation via AxiosCanceler, injects authentication tokens, and allows custom request mutation through transform.requestInterceptors.
  • Response Handling: Cleans up pending requests immediately upon response receipt, transforms response data through transform.responseInterceptors, and centralizes error handling via transform.responseInterceptorsError.
  • Transform Object: Defined in defaultTransform.ts, provides the concrete implementation for all interceptor hooks including beforeRequest for URL manipulation and afterResponse for data extraction.
  • Extensibility: Both interceptors expose a functional API that allows developers to override specific behaviors while maintaining the core cancellation and cleanup logic.

Frequently Asked Questions

How does Celeris Web prevent duplicate concurrent requests?

The request interceptor in [HttpClient.ts](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/HttpClient.ts#L71-L84) registers each outgoing request with the AxiosCanceler class. If an identical request (same method and URL) is dispatched while a previous one is still pending, the new request automatically cancels the previous one, preventing race conditions and unnecessary network load.

Can I remove the default authentication header injection?

Yes. The token injection logic resides in transform.requestInterceptors. To disable it, either set shouldSendTokenInHeader: false in the request options, or provide a custom transform object that omits the default header logic while preserving other interceptor features.

What happens to the pending request map if a response fails?

The response interceptor always executes AxiosCanceler.removePending at lines 92-107 before processing the response body or error. This ensures that failed requests are properly cleared from the pending set, preventing memory leaks and allowing subsequent retry attempts to proceed normally.

How do I add a custom header to every request without modifying the core files?

Extend the transform object and override requestInterceptors. Import the defaultTransform, spread its properties, and add your header logic before or after calling the default interceptor. Pass this custom transform to the HttpClient constructor to apply your changes globally while maintaining the framework's default cancellation and token injection capabilities.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →