Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Features

This chapter consolidates all the features of the Oxidite framework into a single comprehensive overview, as requested in the documentation consolidation rule.

Core Features

1. High-Performance Web Server

  • Built on top of Hyper and Tokio for async/await support
  • Supports HTTP/1.1, HTTP/2, and HTTP/3 protocols
  • Zero-copy transfers for optimal performance
  • Concurrent request handling with async runtime
use oxidite::prelude::*;

async fn hello_world(_req: Request) -> Result<Response> {
    Ok(Response::text("Hello, World!"))
}

#[tokio::main]
async fn main() -> Result<()> {
    let mut router = Router::new();
    router.get("/", hello_world);
    
    Server::new(router)
        .listen("127.0.0.1:3000".parse()?)
        .await
}

2. Type-Safe Request Handling

  • Strongly typed request extractors
  • Compile-time validation of route parameters
  • Automatic serialization/deserialization with Serde
  • Error handling with custom error types
use oxidite::prelude::*;
use serde::Deserialize;

#[derive(Deserialize)]
struct QueryParams {
    page: Option<u32>,
    limit: Option<u32>,
}

async fn api_handler(
    Path(user_id): Path<u32>,
    Query(params): Query<QueryParams>,
    Json(payload): Json<serde_json::Value>
) -> Result<Response> {
    Ok(Response::json(serde_json::json!({
        "user_id": user_id,
        "query_params": params,
        "payload": payload
    })))
}

3. Comprehensive Response System

  • Multiple response types (JSON, HTML, text, etc.)
  • Consistent API with Response::method() pattern
  • Template engine integration
  • Proper HTTP status codes
use oxidite::prelude::*;

async fn various_responses(_req: Request) -> Result<Response> {
    // JSON response
    let json_resp = Response::json(serde_json::json!({ "type": "json" }));
    
    // HTML response
    let html_resp = Response::html("<h1>Hello HTML</h1>");
    
    // Text response
    let text_resp = Response::text("Plain text");
    
    // Empty responses
    let ok_resp = Response::ok();
    let no_content_resp = Response::no_content();
    
    // Return one of them
    Ok(json_resp)
}

Advanced Features

4. Database ORM

  • Model definitions with derive macros
  • Type-safe database operations
  • Relationship management
  • Migrations and schema management
  • Validation and hooks
use oxidite::prelude::*;
use serde::Deserialize;

#[derive(Model, Deserialize)]
#[model(table = "users")]
pub struct User {
    #[model(primary_key)]
    pub id: i32,
    #[model(unique, not_null)]
    pub email: String,
    #[model(not_null)]
    pub name: String,
    #[model(default = "now")]
    pub created_at: String,
}

fn now() -> String {
    chrono::Utc::now().to_rfc3339()
}

async fn user_operations() -> Result<()> {
    // Create
    let user = User {
        id: 0,
        email: "john@example.com".to_string(),
        name: "John Doe".to_string(),
        created_at: now(),
    };
    let saved_user = user.save().await?;
    
    // Read
    let users = User::find_all().await?;
    
    // Update
    let mut user = saved_user;
    user.name = "John Updated".to_string();
    user.save().await?;
    
    // Delete
    user.delete().await?;
    
    Ok(())
}

5. Authentication & Authorization

  • JWT token support
  • Session-based authentication
  • API key authentication
  • OAuth2 integration
  • Role-based access control (RBAC)
  • Two-factor authentication (2FA)
use oxidite::prelude::*;

// JWT authentication middleware
async fn jwt_auth_middleware(req: Request, next: Next) -> Result<Response> {
    // Extract and validate JWT token
    let auth_header = req.headers()
        .get("authorization")
        .and_then(|hv| hv.to_str().ok());
    
    match auth_header {
        Some(auth) if auth.starts_with("Bearer ") => {
            let token = auth.trim_start_matches("Bearer ").trim();
            if verify_jwt(token).await.is_ok() {
                next.run(req).await
            } else {
                Err(Error::Unauthorized("Invalid token".to_string()))
            }
        }
        _ => Err(Error::Unauthorized("Missing token".to_string())),
    }
}

async fn verify_jwt(_token: &str) -> Result<()> {
    // Implementation would verify the JWT
    Ok(())
}

6. Middleware System

  • Global and route-specific middleware
  • Request/response modification
  • Cross-cutting concerns
  • Built-in middleware for common tasks
use oxidite::prelude::*;

async fn logging_middleware(req: Request, next: Next) -> Result<Response> {
    println!("Request: {} {}", req.method(), req.uri());
    let response = next.run(req).await?;
    println!("Response: {}", response.status());
    Ok(response)
}

async fn cors_middleware(req: Request, next: Next) -> Result<Response> {
    let mut response = if req.method() == http::Method::OPTIONS {
        Response::ok()
    } else {
        next.run(req).await?
    };
    
    // Add CORS headers
    use http::header::{HeaderName, HeaderValue};
    response.headers_mut().insert(
        HeaderName::from_static("access-control-allow-origin"),
        HeaderValue::from_static("*")
    );
    
    Ok(response)
}

7. Template Engine

  • Server-side template rendering
  • Template inheritance and composition
  • Context variable binding
  • Direct integration with Response system
use oxidite::prelude::*;
use oxidite_template::{TemplateEngine, Context};

async fn template_example(_req: Request) -> Result<Response> {
    let mut template_engine = TemplateEngine::new();
    
    // Add a template
    template_engine.add_template("welcome", r#"
        <html>
        <head><title>{{ title }}</title></head>
        <body>
            <h1>{{ greeting }}</h1>
            <p>Welcome, {{ name }}!</p>
            <ul>
            {% for item in items %}
                <li>{{ item }}</li>
            {% endfor %}
            </ul>
        </body>
        </html>
    "#)?;
    
    // Create context
    let mut context = Context::new();
    context.set("title", "Welcome Page");
    context.set("greeting", "Hello!");
    context.set("name", "User");
    context.set("items", vec!["Feature 1", "Feature 2", "Feature 3"]);
    
    // Render as response
    let response = template_engine.render_response("welcome", &context)
        .map_err(|e| Error::InternalServerError(e.to_string()))?;
    
    Ok(response)
}

8. Background Jobs & Queues

  • Asynchronous job processing
  • Multiple backend support (Redis, PostgreSQL, memory)
  • Job scheduling and retries
  • Worker management
use oxidite_queue::{Job, Queue, Worker};

// Define a job
#[derive(serde::Serialize, serde::Deserialize)]
struct EmailJob {
    recipient: String,
    subject: String,
    body: String,
}

impl Job for EmailJob {
    type Output = Result<(), String>;
    
    async fn execute(self) -> Self::Output {
        // Send email logic here
        println!("Sending email to {} with subject: {}", 
                 self.recipient, self.subject);
        Ok(())
    }
}

async fn queue_example() -> Result<()> {
    // Create a queue
    let queue = Queue::memory();
    
    // Enqueue a job
    let email_job = EmailJob {
        recipient: "user@example.com".to_string(),
        subject: "Welcome!".to_string(),
        body: "Thank you for joining.".to_string(),
    };
    
    queue.enqueue(email_job).await?;
    
    // Start a worker
    let worker = Worker::new(queue.clone());
    worker.start().await?;
    
    Ok(())
}

9. Real-time Features

  • WebSocket support
  • Server-Sent Events (SSE)
  • Pub/Sub messaging
  • Live updates and notifications
use oxidite::prelude::*;
use oxidite_realtime::websocket::{WebSocket, Message};

async fn websocket_handler(ws: WebSocket) -> Result<()> {
    ws.on_message(|msg| async move {
        match msg {
            Message::Text(text) => {
                println!("Received: {}", text);
                // Echo back
                Ok(Message::Text(format!("Echo: {}", text)))
            }
            Message::Binary(data) => {
                println!("Received binary: {} bytes", data.len());
                Ok(Message::Binary(data))
            }
        }
    }).await?;
    
    Ok(())
}

async fn sse_example(_req: Request) -> Result<Response> {
    use oxidite_realtime::sse::EventStream;
    
    let mut stream = EventStream::new();
    stream.send("Connected", Some("connection"), None).await?;
    
    // Send periodic updates
    tokio::spawn(async move {
        loop {
            tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
            stream.send("Update", Some("data"), None).await.ok();
        }
    });
    
    Ok(stream.response())
}

10. File Upload & Storage

  • Multipart form handling
  • File validation and sanitization
  • Multiple storage backends (local, S3, etc.)
  • Streaming uploads for large files
use oxidite::prelude::*;

async fn upload_handler(_req: Request) -> Result<Response> {
    // In a real implementation, handle multipart form data
    // and save files to configured storage backend
    
    Ok(Response::json(serde_json::json!({
        "status": "uploaded",
        "files": []
    })))
}

11. Security Features

  • Rate limiting
  • CSRF protection
  • XSS prevention
  • SQL injection prevention
  • Input validation
  • Secure headers
use oxidite::prelude::*;

async fn security_middleware(req: Request, next: Next) -> Result<Response> {
    // Rate limiting
    if !is_request_allowed(&req).await {
        return Err(Error::RateLimited);
    }
    
    // Add security headers
    let mut response = next.run(req).await?;
    
    use http::header::{HeaderName, HeaderValue};
    response.headers_mut().insert(
        HeaderName::from_static("x-content-type-options"),
        HeaderValue::from_static("nosniff")
    );
    
    response.headers_mut().insert(
        HeaderName::from_static("x-frame-options"),
        HeaderValue::from_static("DENY")
    );
    
    Ok(response)
}

async fn is_request_allowed(_req: &Request) -> bool {
    // Implementation would check rate limits
    true
}

Enterprise Features

12. Configuration Management

  • Environment-based configuration
  • Multiple configuration sources
  • Type-safe configuration loading
  • Hot reloading support
use oxidite_config::Config;

#[derive(serde::Deserialize)]
struct AppConfig {
    database_url: String,
    server_port: u16,
    jwt_secret: String,
    #[serde(default)]
    debug: bool,
}

async fn load_config() -> Result<AppConfig> {
    let config = Config::builder()
        .add_source(ConfigSource::Env)
        .add_source(ConfigSource::File("config.json"))
        .build()
        .await?;
    
    let app_config: AppConfig = config.try_deserialize()?;
    Ok(app_config)
}

enum ConfigSource {
    Env,
    File(String),
}

13. CLI Tools

  • Project scaffolding
  • Code generation
  • Database migrations
  • Development server with hot reload
# Create a new project
oxidite new my-app

# Generate a model
oxidite generate model User email:string name:string

# Run migrations
oxidite migrate

# Start development server
oxidite dev

14. Testing Utilities

  • Built-in test utilities
  • Mock request/response objects
  • Test server for integration tests
  • Fixture management
use oxidite::prelude::*;
use oxidite_testing::{TestServer, RequestBuilder};

#[cfg(test)]
mod tests {
    use super::*;
    
    #[tokio::test]
    async fn test_hello_world() {
        let server = TestServer::new(|router| {
            router.get("/", hello_world);
        }).await;
        
        let response = server.get("/").send().await;
        assert_eq!(response.status(), 200);
        
        let body = response.text().await;
        assert_eq!(body, "Hello, World!");
    }
}

15. OpenAPI Integration

  • Automatic API documentation generation
  • Schema inference from types
  • Interactive API explorer
  • Validation against OpenAPI spec
use oxidite::prelude::*;
use oxidite_openapi::OpenApi;

#[derive(oxidite_macros::RouteInfo)]
#[openapi(path = "/users/{id}", method = "GET")]
async fn get_user(Path(id): Path<u32>) -> Result<Response> {
    Ok(Response::json(serde_json::json!({
        "id": id,
        "name": format!("User {}", id)
    })))
}

async fn setup_openapi_docs() -> Result<()> {
    let mut openapi = OpenApi::new();
    openapi.add_route(get_user).await?;
    
    // Serve documentation at /docs
    // Implementation would serve the OpenAPI JSON and UI
    
    Ok(())
}

16. Plugin System

  • Extensible architecture
  • Hooks and lifecycle events
  • Third-party integrations
  • Custom middleware and handlers
use oxidite::prelude::*;

trait Plugin {
    fn name(&self) -> &str;
    fn initialize(&self, _router: &mut Router) -> Result<()>;
    fn on_request(&self, _req: &mut Request) -> Result<()>;
    fn on_response(&self, _resp: &mut Response) -> Result<()>;
}

struct LoggingPlugin;

impl Plugin for LoggingPlugin {
    fn name(&self) -> &str { "logging" }
    
    fn initialize(&self, _router: &mut Router) -> Result<()> {
        println!("Logging plugin initialized");
        Ok(())
    }
    
    fn on_request(&self, req: &mut Request) -> Result<()> {
        println!("Processing request: {} {}", req.method(), req.uri());
        Ok(())
    }
    
    fn on_response(&self, resp: &mut Response) -> Result<()> {
        println!("Sending response: {}", resp.status());
        Ok(())
    }
}

Summary

Oxidite is a comprehensive web framework that combines:

  • Performance: Built on async/await with Hyper and Tokio
  • Safety: Type-safe request handling with compile-time validation
  • Flexibility: Extensible architecture with middleware and plugins
  • Security: Built-in security features and best practices
  • Productivity: Rich ecosystem with ORM, authentication, etc.
  • Scalability: Designed for high-concurrency applications

The framework provides everything needed to build modern web applications, from basic routing to enterprise-level features like authentication, real-time communication, and background jobs.