# How to Create and Consume API Endpoints Using the Request Module in Celeris Web

> Learn to create and consume API endpoints in Celeris Web. Use HttpRequestEngine and the @celeris/request module for efficient data fetching with strongly-typed parameters and generics.

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

---

**To create and consume API endpoints in Celeris Web, initialize the global request configuration using `HttpRequestEngine.initRequest` in your application entry point, then write thin TypeScript wrapper functions that call `request.get`, `request.post`, or other HTTP methods from `@celeris/request` with strongly-typed parameters and response generics.**

The `@celeris/request` package provides a centralized Axios wrapper that handles token injection, request cancellation, and global message hooks automatically. This architecture allows you to define type-safe API endpoints in dedicated files while the framework manages interceptors, error handling, and UI feedback.

## Initialize Global Request Configuration with HttpRequestEngine

Before consuming any endpoints, you must configure the request module's global behavior. This one-time setup happens in your application's entry file (typically [`main.ts`](https://github.com/kirklin/celeris-web/blob/main/main.ts) or [`main.js`](https://github.com/kirklin/celeris-web/blob/main/main.js)) using the `HttpRequestEngine.initRequest` method from [`packages/web/request/requestConfiguration.ts`](https://github.com/kirklin/celeris-web/blob/main/packages/web/request/requestConfiguration.ts).

This initialization registers handlers for authentication, error messaging, and request lifecycle events that apply to all subsequent HTTP calls.

### Configure Token Injection and Global Handlers

Pass a factory function to `initRequest` that returns an `HttpRequestOptions` object containing your global handlers:

```typescript
import { createApp } from "vue";
import { HttpRequestEngine } from "@celeris/request";
import { getToken } from "@/store/modules/user";

HttpRequestEngine.initRequest(() => ({
  getToken,
  errorMessageHandler: (msg: string) => console.error("[API error]", msg),
  successMessageHandler: (msg: string) => console.log("[API success]", msg),
  unauthorizedHandler: () => router.replace({ name: "Login" }),
  timeoutHandler: () => console.warn("Request timed out"),
}));

createApp(App).mount("#app");

```

The `getToken` function executes before every request to inject the Authorization header. The `errorMessageHandler` and `successMessageHandler` control global toast notifications, while `unauthorizedHandler` manages 401 responses. These configurations persist across the application lifecycle and merge with per-request options defined in individual endpoint wrappers.

## Create Type-Safe API Endpoint Wrappers

Endpoint definitions reside in dedicated API files (conventionally under `src/apis/`) and import the `request` object from `@celeris/request`. Each wrapper function specifies the HTTP method, URL, parameters, and response type using TypeScript generics.

### Define URL Constants and Parameter Interfaces

Organize your API URLs using a TypeScript enum to prevent hardcoded strings and enable centralized URL management:

```typescript
import type { MessageMode } from "@celeris/request";
import { request } from "@celeris/request";

enum API {
  Login = "/auth/login",
  Logout = "/auth/logout",
  UserInfo = "/user/info",
  PermissionCode = "/auth/permission-code",
}

export interface LoginParams {
  username: string;
  password: string;
}

```

### Implement HTTP Method Wrappers

Create exported functions that invoke the appropriate `request` method with type-safe generics. The first argument contains the Axios configuration (`url`, `params`, `data`), while the optional second argument accepts `RequestOptions` to override global behavior for that specific call:

```typescript
export function loginApi(
  params: LoginParams,
  errorMessageMode: MessageMode = "dialog"
) {
  return request.post<Omit<FakeUserInfo, "extraInfo">>(
    {
      url: API.Login,
      params,
    },
    { errorMessageMode }
  );
}

export function logoutApi(errorMessageMode: MessageMode = "dialog") {
  return request.get<void>(
    {
      url: API.Logout,
    },
    { errorMessageMode }
  );
}

export function userInfoApi(errorMessageMode: MessageMode = "none") {
  return request.get<UserInfo>(
    {
      url: API.UserInfo,
    },
    { errorMessageMode }
  );
}

export { API };

```

The `request` object exposes `get`, `post`, `put`, and `delete` methods, each accepting a generic type parameter `<T>` that defines the return type. The second argument's `errorMessageMode` and `successMessageMode` properties control how the UI displays feedback for that specific endpoint, overriding the global handlers defined in the initialization step.

## Understand the Internal Request Flow

When you call `request.post<T>()` or any other method, the module executes a coordinated sequence across several core files in `packages/web/request/src/`.

### Request Processing Pipeline

1. **Configuration Merge**: In [`HttpClient.ts`](https://github.com/kirklin/celeris-web/blob/main/HttpClient.ts) (lines 61-68), per-request `RequestOptions` merge with the global `HttpRequestConfiguration` stored by `initRequest`.

2. **Interceptor Execution**: The request passes through transforms defined in [`axiosTransform.ts`](https://github.com/kirklin/celeris-web/blob/main/axiosTransform.ts), including `beforeRequest` (which attaches tokens via `AxiosCanceler` and formats dates) and any custom `requestInterceptors` defined globally.

3. **HTTP Execution**: The configured Axios instance dispatches the request.

4. **Response Handling**: The response interceptor runs `afterResponse` to unwrap standard `{ data, code, msg }` envelopes and validate HTTP status codes. If the status indicates success, `successMessageHandler` executes; errors trigger `errorMessageHandler` or `unauthorizedHandler` for 401 responses.

5. **Type Resolution**: The Promise resolves with the generic type `T` specified in the wrapper function, providing full IntelliSense and compile-time type safety.

The [`HttpClient.ts`](https://github.com/kirklin/celeris-web/blob/main/HttpClient.ts) file manages the Axios instance lifecycle, request cancellation tokens, and form-data serialization through the `supportFormData` utility, while [`types.ts`](https://github.com/kirklin/celeris-web/blob/main/types.ts) defines the `RequestOptions` and `RequestResult` interfaces governing all type contracts.

## Consume Endpoints in Vue Components

Import your API wrapper functions directly into Vue components or Pinia stores. The `request` module automatically handles loading states, token refresh, and duplicate request cancellation without additional boilerplate:

```vue
<script setup lang="ts">
import { loginApi } from "@/apis/internal/auth";
import { ref } from "vue";

const form = ref({ username: "", password: "" });
const loading = ref(false);
const error = ref("");

async function submit() {
  loading.value = true;
  error.value = "";
  try {
    const user = await loginApi(form.value);
    // user is typed as Omit<FakeUserInfo, "extraInfo">
    // Handle successful login (store token, redirect, etc.)
  } catch (e) {
    error.value = (e as Error).message;
    // Error already handled by global errorMessageHandler
  } finally {
    loading.value = false;
  }
}
</script>

```

The component receives a fully typed response object while the framework manages the underlying HTTP complexity, including automatic Authorization header injection from the `getToken` function configured during initialization.

## Summary

- **Initialize once**: Call `HttpRequestEngine.initRequest` in [`main.ts`](https://github.com/kirklin/celeris-web/blob/main/main.ts) to configure global token injection, error handlers, and unauthorized redirect behavior.
- **Create thin wrappers**: Define TypeScript functions that call `request.get<T>` or `request.post<T>` with strongly typed parameters and the `RequestOptions` interface for message control.
- **Leverage automatic handling**: The `HttpClient` in [`packages/web/request/src/HttpClient.ts`](https://github.com/kirklin/celeris-web/blob/main/packages/web/request/src/HttpClient.ts) manages interceptors, request cancellation, and form-data serialization without wrapper modifications.
- **Consume with type safety**: Import wrapper functions into components; responses respect the generic type parameter while errors route through centralized handlers.

## Frequently Asked Questions

### What is the difference between HttpClient and the request export in Celeris Web?

**`HttpClient`** is the internal Axios wrapper class defined in [`packages/web/request/src/HttpClient.ts`](https://github.com/kirklin/celeris-web/blob/main/packages/web/request/src/HttpClient.ts) that manages interceptors, request cancellation, and configuration merging. The **`request`** export is a convenience facade that exposes static methods (`get`, `post`, `put`, `delete`) delegating to a singleton `HttpClient` instance, allowing you to invoke HTTP calls without instantiating the client manually.

### How does automatic token injection work in the request module?

During initialization via `HttpRequestEngine.initRequest`, you provide a `getToken` function that returns the current authentication token. This function executes inside the `beforeRequest` transform in [`axiosTransform.ts`](https://github.com/kirklin/celeris-web/blob/main/axiosTransform.ts), automatically attaching the token to the Authorization header of every outgoing request before it reaches the network layer.

### Can I override global error handling for specific API calls?

Yes. Pass a `RequestOptions` object as the second argument to any `request` method call. Properties like `errorMessageMode` and `successMessageMode` accept values such as `"dialog"`, `"message"`, or `"none"` to customize feedback behavior for that specific endpoint, overriding the global `errorMessageHandler` configured in [`main.ts`](https://github.com/kirklin/celeris-web/blob/main/main.ts).

### Where should I place API endpoint definitions in a Celeris Web project?

Conventionally, endpoint wrappers reside in `apps/{app-name}/src/apis/` following the pattern shown in [`apps/admin/src/apis/internal/auth.ts`](https://github.com/kirklin/celeris-web/blob/main/apps/admin/src/apis/internal/auth.ts). Place related endpoints in domain-specific files (e.g., [`auth.ts`](https://github.com/kirklin/celeris-web/blob/main/auth.ts) for authentication, [`user.ts`](https://github.com/kirklin/celeris-web/blob/main/user.ts) for user management), exporting both the API URL enum and the wrapper functions for import by Vue components or state management stores.