How Bella OpenAPI Processes Requests Through Interceptors and Handles Authentication

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.

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, 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 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 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 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 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. The explicit ordering ensures that authentication occurs before rate limiting and quota checks, which depend on the authenticated identity.

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

Practical Code Examples

Standard API request with Authorization header:

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

Gemini-specific endpoint using alternative header:

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 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. 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.

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 →