# Celeris Web Request Interceptor and Response Handling: Architecture and Implementation

> Explore Celeris Web's request interceptor and response handling architecture. Discover how it cancels duplicates, injects auth tokens, and transforms responses globally.

- Repository: [Kirk Lin/celeris-web](https://github.com/kirklin/celeris-web)
- Tags: architecture
- Published: 2026-03-05

---

**Celeris Web implements a dual-interceptor pattern in [`HttpClient.ts`](https://github.com/kirklin/celeris-web/blob/main/HttpClient.ts) that handles duplicate request cancellation, authentication token injection, and global response transformation through a customizable `transform` object defined in [`defaultTransform.ts`](https://github.com/kirklin/celeris-web/blob/main/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()`](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/HttpClient.ts#L71-L84). 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`](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/axiosCancel.ts) 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/main/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`](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/options/transform/defaultTransform.ts#L58-L66). 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`](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/options/transform/defaultTransform.ts#L70-L78). 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/main/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`](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/options/transform/defaultTransform.ts), which can unwrap API envelopes, normalize status codes, or trigger global notifications. The transformed response is then passed to [`transform.afterResponse`](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/options/transform/defaultTransform.ts#L36-L53), 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`](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/options/transform/defaultTransform.ts). 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/main/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.

```typescript
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

```typescript
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

```typescript
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

```typescript
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`](https://github.com/kirklin/celeris-web/blob/main/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`](https://github.com/kirklin/celeris-web/blob/main/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/main/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`](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/options/transform/defaultTransform.ts#L58-L66). 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](https://github.com/kirklin/celeris-web/blob/master/packages/web/request/src/HttpClient.ts#L92-L107) 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.