revoke-gateway

Crates.iorevoke-gateway
lib.rsrevoke-gateway
version0.3.0
created_at2025-07-13 06:21:05.885801+00
updated_at2025-07-13 06:21:05.885801+00
descriptionHigh-performance API gateway built on Cloudflare Pingora for Revoke framework
homepage
repositoryhttps://github.com/revoke/revoke
max_upload_size
id1750035
size90,360
LioRael (LioRael)

documentation

README

revoke-gateway

High-performance API gateway built on Cloudflare Pingora for the Revoke microservices framework.

Overview

revoke-gateway is a production-ready API gateway that provides intelligent routing, load balancing, and resilience features for microservices. Built on top of Cloudflare's Pingora framework, it offers exceptional performance and reliability.

Features

  • High Performance: Built on Pingora's async architecture
  • Service Discovery: Automatic integration with service registries
  • Load Balancing: Uses Pingora's round-robin load balancer
  • Health Checks: TCP health monitoring for backend services
  • Request Routing: Path-based service routing
  • Service Discovery: Dynamic backend discovery from registry
  • Header Forwarding: X-Forwarded-For and custom headers

Quick Start

Basic Usage

use revoke_gateway::{RevokeGateway, GatewayConfig};
use revoke_registry::memory::MemoryRegistry;
use revoke_core::{ServiceRegistry, ServiceInfo, Protocol};
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create service registry
    let registry = Arc::new(MemoryRegistry::new());
    
    // Register a service
    let service = ServiceInfo {
        id: uuid::Uuid::new_v4(),
        name: "user-service".to_string(),
        version: "1.0.0".to_string(),
        address: "127.0.0.1".to_string(),
        port: 3000,
        protocol: Protocol::Http,
        metadata: Default::default(),
    };
    registry.register(service).await?;
    
    // Configure gateway
    let config = GatewayConfig {
        bind: "0.0.0.0:8080".to_string(),
        workers: 4,
        log_level: "info".to_string(),
        enable_health_check: true,
        health_check_interval: 10,
        backend_refresh_interval: 30,
    };
    
    // Create and start gateway
    let gateway = RevokeGateway::new(registry)?;
    gateway.run(config)?;
    
    Ok(())
}

Configuration

The gateway is configured using the GatewayConfig struct:

let config = GatewayConfig {
    bind: "0.0.0.0:8080".to_string(),      // Bind address
    workers: 4,                             // Number of worker threads
    log_level: "info".to_string(),          // Log level
    enable_health_check: true,              // Enable health checks
    health_check_interval: 10,              // Health check interval in seconds
    backend_refresh_interval: 30,           // Backend refresh interval in seconds
};

Or via command line arguments:

revoke-gateway --bind 0.0.0.0:8080 --workers 4 --enable-health-check

Architecture

Request Flow

  1. Incoming Request → Gateway receives HTTP request
  2. Service Extraction → Extracts service name from URL path (e.g., /users/123users)
  3. Service Discovery → Queries registry for service instances
  4. Load Balancing → Creates or reuses Pingora LoadBalancer with round-robin selection
  5. Health Checking → Ensures only healthy backends receive traffic
  6. Request Proxying → Forwards request to selected backend
  7. Header Injection → Adds X-Gateway and X-Forwarded-For headers
  8. Response Processing → Returns response with X-Gateway-Version header

Components

Service Discovery Integration

The gateway automatically discovers services from the registry:

// Services register themselves with the registry
let service = ServiceInfo {
    id: Uuid::new_v4(),
    name: "user-service".to_string(),
    address: "127.0.0.1".to_string(),
    port: 3000,
    protocol: Protocol::Http,
    // ...
};
registry.register(service).await?;

// Gateway discovers services by name from URL path
// Request to /users/123 → looks up "users" service

Load Balancer

The gateway uses Pingora's built-in load balancing:

// Gateway automatically creates load balancers for each service
// with Pingora's round-robin selection algorithm

// When a request comes in:
// 1. Extract service name from path
// 2. Get or create LoadBalancer for that service
// 3. Select a backend using round-robin
// 4. Proxy request to selected backend

The gateway caches load balancers per service for performance.

Health Checks

When enabled, the gateway uses Pingora's TCP health checks:

let config = GatewayConfig {
    enable_health_check: true,
    health_check_interval: 10,  // seconds
    // ...
};

Advanced Usage

Multiple Service Instances

Register multiple instances for load balancing:

// Register 3 instances of user-service
for i in 0..3 {
    let service = ServiceInfo {
        id: Uuid::new_v4(),
        name: "user-service".to_string(),
        address: "127.0.0.1".to_string(),
        port: 3000 + i,
        protocol: Protocol::Http,
        metadata: Default::default(),
    };
    registry.register(service).await?;
}

// Gateway will automatically load balance requests across all instances

Router Module

The gateway includes a basic router for custom routing logic:

use revoke_gateway::router::{Router, Route};

let mut router = Router::new();
router.add_route(Route {
    path_prefix: "/api/v1".to_string(),
    service_name: "api-service".to_string(),
    strip_prefix: true,
});

// Match routes
if let Some(route) = router.match_route("/api/v1/users") {
    println!("Matched service: {}", route.service_name);
}

Integration

With Service Registry

// Memory registry (for testing)
use revoke_registry::memory::MemoryRegistry;
let registry = Arc::new(MemoryRegistry::new());

// Consul registry
use revoke_registry::consul::ConsulRegistry;
let registry = Arc::new(
    ConsulRegistry::new(ConsulConfig::builder()
        .address("http://localhost:8500")
        .build()?)
    .await?
);

Best Practices

  1. Service Naming: Use consistent service names that match URL paths
  2. Health Checks: Enable health checks for production deployments
  3. Multiple Instances: Deploy multiple instances of each service for reliability
  4. Monitoring: Monitor gateway logs for errors and performance issues
  5. Backend Refresh: Set appropriate backend refresh intervals

Troubleshooting

Common Issues

  1. Services Not Found: Check service registry connectivity and service names
  2. 503 Service Unavailable: No healthy backends available - check service health
  3. Connection Refused: Ensure backend services are running on registered ports
  4. Health Check Failures: Verify backend services are responding to TCP connections

Debug Logging

Enable debug logging:

env_logger::init_from_env(
    env_logger::Env::new().default_filter_or("revoke_gateway=debug")
);

Examples

See the examples directory for complete examples:

  • simple_gateway.rs - Basic gateway with single service
  • pingora_load_balancing.rs - Multiple service instances with load balancing
Commit count: 0

cargo fmt