Files
zesdex/apps/interfaces/api/src/lib.rs
T
asepharyana da2ed6da25 feat(tui): add usage overlay and sidebar for displaying usage statistics and tasks
feat(tui): implement status bar with connection and turn state indicators
feat(tui): create workflow panel for agent status and progress visualization
feat(web): introduce web frontend interface with static file serving
feat(ws): add WebSocket interface for real-time communication and session management
2026-07-20 09:04:57 +07:00

100 lines
3.4 KiB
Rust

//! # Zesdex REST API — Axum HTTP server
//!
//! Provides RESTful endpoints for the Zesdex application, enabling
//! web clients, mobile apps, and third-party integrations.
//!
//! ## Architecture
//!
//! ```text
//! src/
//! ├── lib.rs — Module declarations, re-exports, router builder
//! ├── state.rs — ApiState with concrete service implementations
//! ├── error.rs — ApiError enum + IntoResponse
//! ├── dto/ — Request/response DTOs (serde)
//! ├── handlers/ — Axum route handlers
//! └── middleware/ — Tower layers (JWT auth, etc.)
//! ```
//!
//! ## Flow
//!
//! 1. `build_router()` constructs an Axum `Router` with all routes nested.
//! 2. Each handler receives `State<Arc<ApiState>>` or direct extractors.
//! 3. Handlers delegate to application-layer service implementations.
//! 4. Domain/infrastructure errors are mapped to `ApiError` → HTTP status codes.
pub mod dto;
pub mod error;
pub mod handlers;
pub mod middleware;
pub mod state;
pub use error::ApiError;
pub use state::ApiState;
use std::sync::Arc;
use axum::Router;
use tower_http::cors::CorsLayer;
/// Build the API router with all routes registered.
///
/// Flow: create CORS layer → build sub-routers for each resource → nest
/// them under `/api/v1` → attach shared state → return.
///
/// ## Arguments
/// * `state` — shared application state (wrapped in `Arc` for clone-free sharing)
///
/// ## Example
/// ```ignore
/// let state = ApiState::new("/path/to/data");
/// let app = build_router(state);
/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
/// axum::serve(listener, app).await.unwrap();
/// ```
pub fn build_router(state: ApiState) -> Router {
let shared_state: Arc<ApiState> = Arc::new(state);
// CORS layer — permissive for local daemon / development use
let cors = CorsLayer::permissive();
// Combine all sub-routers under a versioned prefix
Router::new()
.nest("/api/v1", api_v1_router())
.layer(cors)
.with_state(shared_state)
}
/// Version 1 API sub-router.
///
/// Groups all resource routes under `/api/v1/*`.
fn api_v1_router() -> Router<Arc<ApiState>> {
use handlers::{auth, chat, conversations, health, sessions};
// Sessions router combines session CRUD + nested conversations
let sessions_router = Router::new()
.route("/", axum::routing::get(sessions::list_sessions_handler))
.route("/", axum::routing::post(sessions::create_session_handler))
.route("/{id}", axum::routing::delete(sessions::delete_session_handler))
// Conversations are sub-resources of sessions
.route(
"/{id}/conversations",
axum::routing::get(conversations::get_conversation_handler),
)
.route(
"/{id}/conversations",
axum::routing::post(conversations::add_message_handler),
)
.route(
"/{id}/conversations/{cid}",
axum::routing::delete(conversations::delete_message_handler),
);
Router::new()
.route("/health", axum::routing::get(health::health))
.nest("/auth", auth::router())
.nest("/sessions", sessions_router)
.nest("/chat", chat::router())
}
// Re-export commonly used types at the crate root for ergonomic access.
pub use axum::http::StatusCode;