Integrating TeaQL with Axum and Redis
TeaQL now includes two Rust integration modules: teaql-web-integration-axum for request handling and teaql-cache-integration-redis for distributed caching.
Both modules keep infrastructure-specific details behind interfaces that application code can access through its request context.
1. The Web Module: Bridging the HTTP Layer and the Security Sandbox
In traditional architectures, the web layer (controllers/routing) and the underlying business logic layer are often completely disconnected. Developers must manually extract tokens, trace IDs, and User-Agents from HTTP headers, then assemble and pass them down to the service layer.
teaql-web-integration-axum connects Axum request extraction with TeaQL's UserContext.
Feature 1: TeaContext Extractor
We implemented a native Axum extractor in the Web module. When a request hits your router, all critical metadata is automatically parsed from the HTTP message and encapsulated into a high-integrity, tamper-proof UserContext:
// Axum router handler
pub async fn load_tasks(ctx: TeaContext, payload: Json<TaskRequest>) -> impl IntoResponse {
// TeaContext has already parsed request metadata into UserContext.
let tasks = Q::tasks()
.purpose("Show the task list for the current request")
.comment("Load tasks for the task-list response")
.execute_for_list(&ctx.0)
.await
.unwrap();
WebResponse::of_list(tasks)
}
Feature 2: Fully Compatible WebResponse
During microservice evolution or frontend refactoring, API compatibility is a major concern. WebResponse implements IntoResponse for status-code resolution and AxumTeaError mapping. Its JSON serialization can retain the response shape expected by an existing Java API client.
Whether it's a frontend application or an AI agent calling the endpoint via OpenAPI, no parser logic needs to be rewritten just because the backend transitioned to Rust.
Feature 3: Native Support for Facets (Aggregated Categorization)
In modern e-commerce, dashboards, or complex business queries, we often need to return not just a list of items but also grouped metadata (such as status counts or temporal distributions) for rendering sidebars. In the search domain, this is referred to as Facets.
teaql-web-integration-axum provides first-class support for Facets. It accepts SmartList directly from the TeaQL Core engine (which comes with multi-dimensional facet data embedded) and formats it into the web response automatically:
// Get the task list and calculate status facets in the same query.
let smart_list = Q::tasks()
.with_status_facets()
.purpose("Populate the task list and its status filters")
.comment("Load tasks with status facets")
.execute_for_smart_list(&ctx)
.await?;
// Convert it into a standard Web API response containing both data and facets with one line of code
WebResponse::from_smart_list(smart_list)
Once the frontend receives the JSON, the data array is used to render the main list, and the facets dictionary is immediately ready to populate the sidebar filter options.
2. The Red Module: Distributed Cache with a Single Line of Code
As concurrency increases, single-machine in-memory cache often reaches its limits. To address this, we launched the teaql-cache-integration-redis module.
The core philosophy of this module is: do not change any upper-level business code; simply replace the underlying provider to transition smoothly from single-machine to distributed caching.
It fully implements TeaQL's runtime DataStore trait. Developers and AI agents write the exact same, simple and unified syntax:
// Business code always uses this single syntax, independent of physical storage
ctx.put("daily_task_stats", stats_value, Some(3600)).await;
let stats = ctx.get("daily_task_stats").await;
At the initialization level, the architect only needs to inject the RedisDataStore:
let redis_store = RedisDataStore::new("redis://127.0.0.1:6379/0").await?;
let runtime = TeaRuntime::builder()
.with_data_store(redis_store)
.build();
Summary: Keeping Infrastructure Behind Stable Boundaries
The introduction of these two new modules is far more than just adding a couple of adapters. Their essence lies in reducing the external entropy of the system:
- The Web module collapses raw, messy HTTP protocols into a structured
UserContext. - The Red module abstracts complex Redis drivers into a unified
DataStoreinterface.
Application code—and coding agents working on it—can follow one pathway: obtain the request context, access domain data, and return a response. Provider setup remains an explicit infrastructure responsibility.
The integrations do not eliminate HTTP or Redis complexity; they keep that complexity out of ordinary domain workflows.
