# How Bella OpenAPI Processes Requests Through Interceptors and Handles Authentication

> Discover how Bella OpenAPI processes requests through its interceptor chain, handling authentication, rate limiting, and quota enforcement before reaching controllers.

- Repository: [Ke Technologies/bella-openapi](https://github.com/lianjiatech/bella-openapi)
- Tags: deep-dive
- Published: 2026-03-06

---

**Bella OpenAPI routes every HTTP request through a strictly ordered chain of Spring MVC interceptors that initialize context, authenticate via API keys, enforce QPS rate limits, and validate monthly quotas before the request reaches the controller.**

Bella OpenAPI is a Spring Boot-based API gateway and management platform designed for routing AI model inference requests. Understanding the request flow through Bella OpenAPI interceptors is essential for debugging authentication failures, optimizing performance, and implementing custom middleware. The pipeline uses a combination of servlet filters and ordered `HandlerInterceptor` implementations to enforce cross-cutting concerns before business logic executes.

## The Request Processing Pipeline

The flow begins with a servlet filter and continues through five ordered interceptors defined in [`api/server/src/main/java/com/ke/bella/openapi/configuration/WebConfig.java`](https://github.com/lianjiatech/bella-openapi/blob/main/api/server/src/main/java/com/ke/bella/openapi/configuration/WebConfig.java).

### Context Initialization with OpenapiRequestFilter

Before Spring MVC interceptors execute, the `OpenapiRequestFilter` (a servlet filter) creates thread-local storage for the request lifecycle.

Located at [`api/server/src/main/java/com/ke/bella/openapi/intercept/OpenapiRequestFilter.java`](https://github.com/lianjiatech/bella-openapi/blob/main/api/server/src/main/java/com/ke/bella/openapi/intercept/OpenapiRequestFilter.java), this filter:

- Instantiates `BellaContext` and `EndpointContext`
- Records request timestamps
- Stores request headers for downstream use
- Clears contexts after the request completes to prevent memory leaks

### Async Request Handling

The `ConcurrentStartInterceptor` in [`api/spi/src/main/java/com/ke/bella/openapi/server/intercept/ConcurrentStartInterceptor.java`](https://github.com/lianjiatech/bella-openapi/blob/main/api/spi/src/main/java/com/ke/bella/openapi/server/intercept/ConcurrentStartInterceptor.java) marks asynchronous Servlet 3.0 requests with `ASYNC_REQUEST_MARKER`. This prevents later interceptors from processing the same request twice during async dispatch.

### Authentication and Authorization

The `AuthorizationInterceptor` (order 100) in [`api/server/src/main/java/com/ke/bella/openapi/intercept/AuthorizationInterceptor.java`](https://github.com/lianjiatech/bella-openapi/blob/main/api/server/src/main/java/com/ke/bella/openapi/intercept/AuthorizationInterceptor.java) handles the core authentication logic.

It extracts the API key using three strategies:

1. **Internal Operator context**: For manager-level calls, it reads `Operator.getManagerAk()` from the existing `BellaContext`
2. **Standard Authorization header**: For regular API calls, it treats the `Authorization` header value directly as the API key
3. **Alternative protocol headers**: For provider-specific endpoints like Gemini, it checks `x-goog-api-key` when the URI matches Gemini model paths

The interceptor calls `ApikeyService.verifyAuth` to validate the key and retrieve `ApikeyInfo`. If validation fails, it throws `BellaException.AuthorizationException`, which translates to a `401 Unauthorized` response. Upon success, it stores role information in the `Operator` and places `ApikeyInfo` into `EndpointContext` for downstream interceptors.

### QPS Rate Limiting

The `QpsRateLimitInterceptor` (order 109) in [`api/server/src/main/java/com/ke/bella/openapi/intercept/QpsRateLimitInterceptor.java`](https://github.com/lianjiatech/bella-openapi/blob/main/api/server/src/main/java/com/ke/bella/openapi/intercept/QpsRateLimitInterceptor.java) enforces per-key query-per-second limits.

It retrieves `ApikeyInfo` from `EndpointContext` and queries `QpsLimiterManager` to verify the current request rate against the key's `qpsLimit`. If exceeded, it adds a `Retry-After: 1` header and raises `BellaException.RateLimitException`.

### Monthly Quota Enforcement

The `MonthQuotaInterceptor` (order 110) in [`api/server/src/main/java/com/ke/bella/openapi/intercept/MonthQuotaInterceptor.java`](https://github.com/lianjiatech/bella-openapi/blob/main/api/server/src/main/java/com/ke/bella/openapi/intercept/MonthQuotaInterceptor.java) prevents cost overruns.

It loads the month-to-date cost via `ApikeyService.loadCost` for the API key or its parent key. If the accumulated cost reaches the configured `monthQuota`, it throws `BellaException.RateLimitException`, halting the request before it reaches the controller.

## Interceptor Configuration and Ordering

The registration and ordering logic resides in [`api/server/src/main/java/com/ke/bella/openapi/configuration/WebConfig.java`](https://github.com/lianjiatech/bella-openapi/blob/main/api/server/src/main/java/com/ke/bella/openapi/configuration/WebConfig.java). The explicit ordering ensures that authentication occurs before rate limiting and quota checks, which depend on the authenticated identity.

```java
// QPS 限流拦截器（order=109）- 在 AuthorizationInterceptor(100) 之后，MonthQuotaInterceptor(110) 之前
registry.addInterceptor(qpsRateLimitInterceptor) …

```

## Practical Code Examples

Standard API request with Authorization header:

```http
GET /v1/chat/completions HTTP/1.1
Host: api.example.com
Authorization: sk-abcdef1234567890
Content-Type: application/json

```

Gemini-specific endpoint using alternative header:

```http
POST /v1beta/models/gemini-pro:generateContent HTTP/1.1
Host: api.example.com
x-goog-api-key: sk-gemini-xyz987
Content-Type: application/json

```

## Summary

- Bella OpenAPI uses a servlet filter (`OpenapiRequestFilter`) to initialize request contexts before Spring MVC interceptors execute.
- The interceptor chain follows a strict order: Authentication (100) → QPS Rate Limiting (109) → Monthly Quota (110).
- Authentication supports multiple key sources: internal `Operator` context, standard `Authorization` headers, and provider-specific alternatives like `x-goog-api-key`.
- Rate limiting and quota enforcement depend on the `ApikeyInfo` stored in `EndpointContext` during the authentication phase.
- All components are configured in [`WebConfig.java`](https://github.com/lianjiatech/bella-openapi/blob/main/WebConfig.java) with explicit ordering to ensure security checks precede resource-intensive operations.

## Frequently Asked Questions

### How does Bella OpenAPI extract the API key from incoming requests?

The `AuthorizationInterceptor` extracts the API key using three strategies: for manager-level internal calls it reads from `Operator.getManagerAk()` in the current `BellaContext`; for standard API calls it uses the value of the HTTP `Authorization` header directly; and for provider-specific endpoints like Gemini it checks the `x-goog-api-key` header when the request URI matches specific model paths.

### What happens if a request exceeds the QPS rate limit?

When the `QpsRateLimitInterceptor` detects that a request exceeds the key's configured `qpsLimit`, it adds a `Retry-After: 1` header to the response and throws `BellaException.RateLimitException`. This results in a rate limit error response before the request reaches the controller.

### In what order do the interceptors execute, and why does it matter?

The interceptors execute in this order: `AuthorizationInterceptor` (order 100), `QpsRateLimitInterceptor` (order 109), and `MonthQuotaInterceptor` (order 110). This ordering is critical because rate limiting and quota enforcement depend on the authenticated identity and `ApikeyInfo` stored in `EndpointContext` during the authentication phase. Authentication must occur first to establish the security context required for subsequent checks.

### Where is the interceptor chain configured in the Bella OpenAPI codebase?

The interceptor registration and ordering logic is defined in [`api/server/src/main/java/com/ke/bella/openapi/configuration/WebConfig.java`](https://github.com/lianjiatech/bella-openapi/blob/main/api/server/src/main/java/com/ke/bella/openapi/configuration/WebConfig.java). This Spring configuration class explicitly sets the order values for each interceptor to ensure the correct execution sequence from authentication through rate limiting to quota enforcement.