ruvector/crates/ruvector-server/src/lib.rs
Claude ed83f8f1d3 feat: Add 5 new production crates with WASM/Node.js integration
New Crates:
- ruvector-server: REST API server using axum (collections, points, health endpoints)
- ruvector-collections: Multi-collection management with aliases
- ruvector-filter: Advanced payload indexing (9 index types, geo, full-text)
- ruvector-snapshot: Backup/restore with gzip compression and checksums
- ruvector-metrics: Prometheus metrics and health checks

Integrations:
- Node.js NAPI-RS: CollectionManager, filters, metrics, health endpoints
- WASM: CollectionManager, FilterBuilder (with feature flag)

Performance Benchmarks:
- HNSW search: 41-151µs (k=1 to k=100)
- Distance calc: 16-142ns (128-1536 dims)
- Batch distances: 278µs (1000x384)

All crates compile in both debug and release modes.
2025-11-25 03:00:28 +00:00

125 lines
3.2 KiB
Rust

//! ruvector-server: REST API server for rUvector vector database
//!
//! This crate provides a REST API server built on axum for interacting with rUvector.
pub mod error;
pub mod routes;
pub mod state;
use axum::{routing::get, Router};
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use tower_http::{
compression::CompressionLayer,
cors::{Any, CorsLayer},
trace::TraceLayer,
};
pub use error::{Error, Result};
pub use state::AppState;
/// Server configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
/// Server host address
pub host: String,
/// Server port
pub port: u16,
/// Enable CORS
pub enable_cors: bool,
/// Enable compression
pub enable_compression: bool,
}
impl Default for Config {
fn default() -> Self {
Self {
host: "127.0.0.1".to_string(),
port: 6333,
enable_cors: true,
enable_compression: true,
}
}
}
/// Main server structure
pub struct RuvectorServer {
config: Config,
state: AppState,
}
impl RuvectorServer {
/// Create a new server instance with default configuration
pub fn new() -> Self {
Self {
config: Config::default(),
state: AppState::new(),
}
}
/// Create a new server instance with custom configuration
pub fn with_config(config: Config) -> Self {
Self {
config,
state: AppState::new(),
}
}
/// Build the router with all routes
fn build_router(&self) -> Router {
let mut router = Router::new()
.route("/health", get(routes::health::health_check))
.route("/ready", get(routes::health::readiness))
.nest("/collections", routes::collections::routes())
.merge(routes::points::routes())
.with_state(self.state.clone());
// Add middleware layers
router = router.layer(TraceLayer::new_for_http());
if self.config.enable_compression {
router = router.layer(CompressionLayer::new());
}
if self.config.enable_cors {
let cors = CorsLayer::new()
.allow_origin(Any)
.allow_methods(Any)
.allow_headers(Any);
router = router.layer(cors);
}
router
}
/// Start the server
///
/// # Errors
///
/// Returns an error if the server fails to bind or start
pub async fn start(self) -> Result<()> {
let addr: SocketAddr = format!("{}:{}", self.config.host, self.config.port)
.parse()
.map_err(|e| Error::Config(format!("Invalid address: {}", e)))?;
let router = self.build_router();
tracing::info!("Starting ruvector-server on {}", addr);
let listener = tokio::net::TcpListener::bind(addr)
.await
.map_err(|e| Error::Server(format!("Failed to bind to {}: {}", addr, e)))?;
axum::serve(listener, router)
.await
.map_err(|e| Error::Server(format!("Server error: {}", e)))?;
Ok(())
}
}
impl Default for RuvectorServer {
fn default() -> Self {
Self::new()
}
}