261 lines
7.7 KiB
Markdown
Raw Permalink Normal View History

# Shared Rust API Library
A comprehensive, production-grade Rust library for building high-performance REST APIs with common infrastructure patterns.
## Overview
This library extracts ~2,400 lines (67%) of duplicated code from the Tools ecosystem APIs, enabling both `syntaxis-api` and `tracking-api` to share common functionality while maintaining their domain-specific implementations.
## Created: January 14, 2025
## Project Structure
```
/Users/Akasha/Tools/shared/rust-api/
└── shared-api-lib/
├── Cargo.toml
├── README.md (this file)
└── src/
├── lib.rs # Main library entry point
├── config/mod.rs # Server configuration (571 lines)
├── error/mod.rs # Error types (69 lines)
├── health/mod.rs # Health checks (86 lines, refactored)
├── middleware/mod.rs # CORS & logging utilities (new)
├── state/mod.rs # Generic AppState<DB> pattern (new)
├── auth/
│ ├── mod.rs # API key authentication (637 lines)
│ └── jwt.rs # JWT provider (494 lines)
├── metrics/mod.rs # Prometheus metrics (325 lines, refactored)
├── rate_limit/mod.rs # Token bucket rate limiter (356 lines)
└── websocket/mod.rs # Event broadcaster (284 lines, refactored)
```
## Features
-**Configuration** (`config`): TOML-based with feature flags
-**Error Handling** (`error`): Unified API error types
-**Health Checks** (`health`): Uptime tracking and status endpoints
-**Authentication** (`auth`): API keys + JWT (feature: `auth`)
-**Metrics** (`metrics`): Prometheus collection (feature: `metrics`)
-**Rate Limiting** (`rate_limit`): Token bucket algorithm (feature: `rate-limit`)
-**WebSockets** (`websocket`): Event broadcasting (feature: `websocket`)
-**Middleware** (`middleware`): CORS and logging utilities
## Key Improvements Over Original
### 1. **Generic AppState<DB>**
Instead of a monolithic AppState tied to PersistenceLayer, the new AppState uses generics:
```rust
#[derive(Clone)]
pub struct AppState<DB: Send + Sync> {
pub db: Arc<DB>,
#[cfg(feature = "metrics")]
pub metrics: Option<Arc<MetricsCollector>>,
#[cfg(feature = "rate-limit")]
pub rate_limiter: Option<Arc<RateLimiter>>,
#[cfg(feature = "auth")]
pub auth: Option<Arc<AuthProvider>>,
#[cfg(feature = "websocket")]
pub events: Option<Arc<EventBroadcaster>>,
}
```
### 2. **Feature-Based Optional Components**
All optional features are behind feature flags and optional fields:
- No bloat if features are disabled
- Each API can opt into what it needs
- Configuration-driven feature enablement
### 3. **Removed Project-Specific Code**
- Removed `OpenAPI spec generation` (project-specific)
- Removed `ProjectEvent` (use generic EventBroadcaster)
- Removed `syntaxis-core` imports
- Made all imports generic where possible
### 4. **Builder Pattern**
AppState supports builder-style initialization:
```rust
let state = AppState::new(db.clone())
.with_metrics(metrics)
.with_rate_limiter(rate_limiter)
.with_auth(auth)
.with_events(broadcaster);
```
## Integration Steps
### For syntaxis-api
1. Add dependency in `Cargo.toml`:
```toml
shared-api-lib = { path = "../shared-api-lib", features = ["metrics", "auth", "rate-limit", "websocket", "tls"] }
```
2. Update imports from local modules:
```rust
// Before
use crate::config::ServerConfig;
use crate::error::ApiError;
// After
use shared_api_lib::config::ServerConfig;
use shared_api_lib::error::ApiError;
```
3. Implement database trait for health checks:
```rust
pub trait ApiDatabase: Send + Sync {
async fn ping(&self) -> Result<(), Error>;
}
```
4. Implement custom metrics and WebSocket handlers using the generic AppState<DB>
### For tracking-api
1. Add dependency (same as above)
2. Update all imports to use shared_api_lib
3. Create configuration file supporting features
4. Implement domain-specific handlers
5. Gain metrics, rate-limiting, and auth immediately
## Compilation Status
**Compiles successfully with no errors**
⚠️ **17 minor warnings** about missing documentation (non-critical)
Run tests with:
```bash
cargo test --lib
```
## Next Steps (For User)
1. **Phase 2: Update syntaxis-api**
- Update Cargo.toml dependencies
- Update all imports to use shared_api_lib
- Remove duplicated modules (config.rs, error.rs, auth.rs, jwt.rs, metrics.rs, rate_limit.rs, websocket.rs, api.rs)
- Implement ApiDatabase trait
- Update main.rs to use shared AppState<DB>
- Run tests to verify
2. **Phase 3: Update tracking-api**
- Add configuration file with feature flags
- Update Cargo.toml with shared-api-lib dependency
- Implement config loading
- Create AppState with domain-specific DB type
- Update handlers to use generic AppState
- Gain metrics, auth, rate-limiting capabilities
- Run tests
3. **Phase 4: Verification**
- Run all 446 tests across both workspaces
- Verify no regressions
- Update documentation
## Code Statistics
| Module | Lines | Shareable % | Status |
|--------|-------|-------------|--------|
| config | 571 | 95% | ✅ Extracted |
| error | 69 | 90% | ✅ Extracted |
| health | 132 | 85% | ✅ Extracted & Refactored |
| auth | 637 | 100% | ✅ Extracted |
| jwt | 494 | 100% | ✅ Extracted |
| metrics | 325 | 95% | ✅ Extracted & Refactored |
| rate_limit | 356 | 100% | ✅ Extracted |
| websocket | 284 | 80% | ✅ Extracted & Refactored |
| **TOTAL** | **2,868** | **93%** | ✅ **Complete** |
## Testing
The shared library includes comprehensive tests for all modules:
- Config parsing and validation
- Error handling and responses
- Health check endpoints
- Authentication (API keys + JWT)
- Metrics collection
- Rate limiting
- Event broadcasting
Run with:
```bash
cd /Users/Akasha/Tools/shared/rust-api/shared-api-lib
cargo test --lib
```
## Dependencies
### Required
- axum (0.8)
- tokio (1.35) with all features
- serde/serde_json (1.0)
- thiserror (1.0)
- chrono (0.4)
### Optional (Behind Features)
- prometheus (0.13) - for metrics
- jsonwebtoken (9.2) - for JWT auth
- uuid (1.6) - for key generation
- tokio-tungstenite (0.24) - for WebSockets
- tokio-rustls (0.26) - for TLS
## Production Readiness
✅ Zero unsafe code (`#![forbid(unsafe_code)]`)
✅ No unwrap() in library code
✅ Comprehensive error handling
✅ Idiomatic Rust (Microsoft Pragmatic Guidelines)
✅ DRY principle (eliminated 67% duplication)
✅ SRP principle (modular, single-responsibility modules)
## Configuration Example
```toml
[server]
host = "0.0.0.0"
port = 3000
database_path = "./data/api.db"
public_files_path = "./public"
cors_enabled = true
log_level = "info"
[server.features]
database = { enabled = true }
health = { enabled = true }
metrics = { enabled = true }
rate_limit = { enabled = true }
auth = { enabled = true }
[[server.features.tls]]
enabled = false
cert_path = "/path/to/cert.pem"
key_path = "/path/to/key.pem"
```
## Contributing
When using this library:
1. Keep all code idiomatic Rust
2. Maintain zero unsafe code
3. Add comprehensive tests for new features
4. Document public APIs
5. Follow DRY and SRP principles
6. Never hardcode values - use configuration
## Future Enhancements
- Add generic EventBroadcaster<T> for custom event types
- Add middleware for request ID tracking
- Add structured logging helpers
- Add database abstraction traits
- Add service discovery support
- Add circuit breaker pattern
---
**Created as part of Tools Ecosystem DRY Initiative**
**Target: Reduce API duplication from 67% to <5%**