//! Database Gateway - HTTP/REST API for Synor Database. //! //! Provides external access to database operations via REST API. //! //! # Endpoints //! //! ## Key-Value Operations //! - `GET /kv/:key` - Get value //! - `PUT /kv/:key` - Set value //! - `DELETE /kv/:key` - Delete key //! - `POST /kv/batch` - Batch operations //! //! ## Document Operations //! - `POST /db/:database/collections` - Create collection //! - `GET /db/:database/:collection` - Query documents //! - `POST /db/:database/:collection` - Insert document //! - `PUT /db/:database/:collection/:id` - Update document //! - `DELETE /db/:database/:collection/:id` - Delete document //! //! ## Vector Operations //! - `POST /db/:database/vectors` - Insert embeddings //! - `POST /db/:database/vectors/search` - Similarity search //! //! ## Time-Series Operations //! - `POST /db/:database/metrics/:name` - Record metric //! - `GET /db/:database/metrics/:name` - Query metrics pub mod auth; pub mod handlers; pub mod router; pub mod server; pub use auth::{ApiKey, AuthConfig, AuthMiddleware}; pub use router::create_router; pub use server::{GatewayConfig, GatewayServer}; use crate::error::DatabaseError; use serde::{Deserialize, Serialize}; /// API response wrapper. #[derive(Debug, Serialize, Deserialize)] pub struct ApiResponse { /// Whether the request succeeded. pub success: bool, /// Response data (if successful). #[serde(skip_serializing_if = "Option::is_none")] pub data: Option, /// Error message (if failed). #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, /// Request ID for tracing. #[serde(skip_serializing_if = "Option::is_none")] pub request_id: Option, } impl ApiResponse { /// Creates a successful response. pub fn ok(data: T) -> Self { Self { success: true, data: Some(data), error: None, request_id: None, } } /// Creates an error response. pub fn error(message: impl Into) -> Self { Self { success: false, data: None, error: Some(message.into()), request_id: None, } } /// Sets the request ID. pub fn with_request_id(mut self, id: impl Into) -> Self { self.request_id = Some(id.into()); self } } impl From> for ApiResponse { fn from(result: Result) -> Self { match result { Ok(data) => ApiResponse::ok(data), Err(e) => ApiResponse::error(e.to_string()), } } } /// Pagination parameters. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Pagination { /// Number of items to skip. #[serde(default)] pub skip: usize, /// Maximum items to return. #[serde(default = "default_limit")] pub limit: usize, } fn default_limit() -> usize { 100 } impl Default for Pagination { fn default() -> Self { Self { skip: 0, limit: default_limit(), } } } /// Usage metrics for billing. #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct UsageMetrics { /// Read operations count. pub reads: u64, /// Write operations count. pub writes: u64, /// Vector search operations. pub vector_searches: u64, /// Storage used (bytes). pub storage_bytes: u64, /// Data transferred (bytes). pub bandwidth_bytes: u64, }