Frontend Development 16 min read

Design and Implementation of a Unified Front-End Request Library Based on Middleware Pattern

Bilibili created a unified front‑end request library using a Koa‑style middleware “onion” architecture—ConfigCtrl, AssembleCtrl, and RequestCtrl—to standardize error handling, cut code redundancy, improve performance, and provide consistent, extensible API calls across SSR/CSR, Vue2/Vue3, and in‑app H5 environments.

Bilibili Tech
Bilibili Tech
Bilibili Tech
Design and Implementation of a Unified Front-End Request Library Based on Middleware Pattern

Front‑end engineers frequently need to call back‑end APIs, and there are many existing approaches such as XHR, Axios and fetch. To address the fragmentation and inefficiencies of these solutions, Bilibili designed a unified request library that provides standardized error handling, reduces code redundancy, smooths style differences, lowers documentation overhead and improves IDE assistance.

The main pain points that motivated the library are:

Code redundancy and high maintenance cost caused by multiple versions of request utilities (SSR/CSR, Vue2/Vue3, in‑app H5, etc.).

Performance issues due to bloated libraries.

Lack of coordinated evolution between front‑end and back‑end, leading to duplicated implementations for the same back‑end capability.

After researching community solutions (Axios, native fetch, etc.) the team concluded that a middleware‑based design offers the most flexibility. The library adopts the “onion” model inspired by Koa, where each middleware handles a specific concern (logging, error handling, data conversion, etc.) and the request/response passes through the chain forward and backward.

Architecture

The system is organized around three controllers:

ConfigCtrl : creates the middleware context and stores configuration for each request.

AssembleCtrl : assembles global and temporary middlewares together with a payload, allowing addition, removal or disabling of middlewares.

RequestCtrl : builds the final request function, combines it with the context, and executes the HTTP call.

Middleware are defined by an abstract base class, enabling type checking and consistent interfaces. Global middlewares are registered at instantiation, while temporary middlewares can be attached per request via the with API. The library also distinguishes Fetch‑specific middleware from others, placing the Fetch middleware at the core of the onion.

Example of the core type definitions:

export interface IHttpServiceInit {
  baseURL?: FetchBaseURL;
  fetch?: IHttpSvcMiddleware;
  middlewares?: IHttpSvcMiddleware[];
}

class HttpService {
  constructor(initConfig?: IHttpServiceInit | IHttpSvcMiddleware[]);
  // ... other methods
}

Example of registering a global middleware and using the chainable API:

const globalMeta = (ctx, next, config) => {
  if (config?.payload?.active) {
    ctx.request.params["meta"] = {
      platform: "web",
      device: ""
    };
  }
  await next();
};

class GlobalMeta extends Middleware {
  name = "GLOBA_META";
  constructor() { super(globalMeta); }
}

const httpSvc = new HttpService([new GlobalMeta()]);
// Register but not active by default
httpSvc.with("GLOBAL_META", { active: true });

httpSvc
  .with(encodeHandler)
  .with(reportHandler)
  .with('RES_DATA', { type: 'text' })
  .disable('RES_EXTRACT')
  .with('SERVER_SIDE', { headers: context.headers || {} })
  .request({ url: '/xxx', params: { id: 1 } });

The library also separates middleware into its own npm package, reducing the learning curve for users and allowing independent versioning.

Visual illustrations (omitted here) show the onion model, the controller interaction diagram, and the overall design flow.

Benefits of adopting the unified request library include a single entry point for company‑wide capabilities, reduced development effort, consistent behavior across platforms (web, native H5, etc.), and a solid foundation for a sustainable front‑end ecosystem.

For more details, examples and community‑contributed middlewares, refer to the project’s GitHub repository: https://github.com/bilibili/http-service .

TypeScriptfrontendMiddlewareHTTPDesign PatternRequest library
Bilibili Tech
Written by

Bilibili Tech

Provides introductions and tutorials on Bilibili-related technologies.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.