https://github.com/danielsarmiento04/ben

Powerful Api Gateway written in Rust

https://github.com/danielsarmiento04/ben

Science Score: 26.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (11.9%) to scientific vocabulary

Keywords

actix-web apigateway reqwest rust
Last synced: 9 months ago · JSON representation

Repository

Powerful Api Gateway written in Rust

Basic Info
  • Host: GitHub
  • Owner: DanielSarmiento04
  • License: mit
  • Language: Rust
  • Default Branch: main
  • Homepage:
  • Size: 719 KB
Statistics
  • Stars: 7
  • Watchers: 1
  • Forks: 1
  • Open Issues: 0
  • Releases: 1
Topics
actix-web apigateway reqwest rust
Created over 1 year ago · Last pushed 9 months ago
Metadata Files
Readme License

Readme.md

Ben 🚀

[![Rust](https://img.shields.io/badge/rust-2021-orange.svg)](https://www.rust-lang.org/) [![Crates.io](https://img.shields.io/crates/v/ben?color=blue)](https://crates.io/crates/ben) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Build Status](https://img.shields.io/github/workflow/status/DanielSarmiento04/Ben/CI)](https://github.com/DanielSarmiento04/Ben/actions) [![Security audit](https://img.shields.io/badge/security-audit-success.svg)](https://github.com/DanielSarmiento04/Ben/security) [![codecov](https://codecov.io/gh/DanielSarmiento04/Ben/branch/main/graph/badge.svg)](https://codecov.io/gh/DanielSarmiento04/Ben)

A blazingly fast, high-performance HTTP gateway and reverse proxy service built with Rust. Featuring intelligent request routing, dynamic path parameters, and enterprise-grade reliability.

[🚀 Quick Start](#-quick-start) • [📖 Documentation](#-documentation) • [✨ Features](#-features) • [🛠️ Examples](#%EF%B8%8F-examples) • [🤝 Contributing](#-contributing)

🎯 Overview

Ben is a production-ready HTTP gateway service that acts as an intelligent reverse proxy, providing advanced request routing capabilities with dynamic path parameter support. Built from the ground up with Actix Web and Reqwest, it delivers exceptional performance while maintaining simplicity and configurability.

Why Ben?

  • 🔥 Performance: Built with Rust for maximum throughput and minimal latency
  • 🧠 Smart Routing: Dynamic path parameters with regex-based pattern matching
  • 🛡️ Production Ready: Comprehensive error handling, logging, and monitoring
  • 🔧 Zero Config: Works out of the box with sensible defaults
  • 📊 Observable: Rich logging and metrics for production environments

📋 Table of Contents

🎯 Overview

Ben is a lightweight, configurable HTTP gateway service that acts as a reverse proxy, routing external requests to internal services based on path patterns. Built with Actix Web and Reqwest, it provides high-performance request forwarding with comprehensive error handling and logging.

Key Use Cases

  • API Gateway: Route external API calls to internal microservices
  • Service Mesh: Proxy requests between services with path transformation
  • Load Balancing: Distribute requests across multiple backend services
  • Development Proxy: Route development requests to different environments

✨ Features

Core Capabilities

  • 🔄 Intelligent Request Routing: Advanced path matching with dynamic parameter support
  • 🎯 Dynamic Path Parameters: Support for {param} placeholders in routes (e.g., /users/{id})
  • 🛣️ Path Transformation: Flexible external-to-internal path mapping and rewriting
  • 🔧 HTTP Method Filtering: Granular method restrictions per route configuration
  • High-Performance Architecture: Async/await with connection pooling and request batching

Production Features

  • 🏗️ Enterprise Architecture: Built with Actix Web for production workloads
  • 🎨 Rich Observability: Structured logging with ANSI colors and configurable levels
  • 📊 Comprehensive Error Handling: Typed errors with proper HTTP status code mapping
  • Security: Request validation, timeout handling, and upstream protection
  • 🚀 Scalability: Connection pooling, async processing, and resource optimization

Developer Experience

  • 📝 JSON Configuration: Simple, declarative route definitions
  • Hot Reloading: Development-friendly configuration updates
  • 🧪 Comprehensive Testing: Unit and integration tests with performance benchmarks
  • 📖 Rich Documentation: Extensive examples and API reference
  • 🛠️ Docker Support: Container-ready with optimized images

🏗️ Architecture

Ben follows a clean, modular architecture designed for high performance and maintainability:

```mermaid graph TB Client[Client Applications] --> LB[Load Balancer] LB --> Ben1[Ben Instance 1] LB --> Ben2[Ben Instance 2] LB --> Ben3[Ben Instance 3]

Ben1 --> Route[Route Matcher Engine]
Ben1 --> Pool[Connection Pool]

Route --> Static[Static Route Cache]
Route --> Dynamic[Dynamic Pattern Matcher]

Pool --> Service1[Microservice A]
Pool --> Service2[Microservice B]
Pool --> Service3[Microservice C]

Ben1 --> Metrics[Metrics & Logging]
Metrics --> Prometheus[Prometheus]
Metrics --> Jaeger[Jaeger Tracing]

```

Core Components

1. Route Matching Engine

rust // High-performance route matcher with pre-compiled regex patterns pub struct RouteMatcher { static_routes: HashMap<String, Router>, // O(1) lookup for exact matches dynamic_routes: Vec<CompiledRoute>, // Compiled regex patterns }

2. Connection Management

rust // Optimized HTTP client with connection pooling Client::builder() .pool_idle_timeout(Duration::from_secs(30)) .pool_max_idle_per_host(32) .timeout(Duration::from_secs(30))

3. Request Processing Pipeline

  1. Request Validation - Method and path validation
  2. Route Matching - Static lookup → Dynamic pattern matching
  3. Path Transformation - Parameter substitution and path rewriting
  4. Request Forwarding - Async HTTP request with timeout
  5. Response Streaming - Direct response forwarding with header filtering

Deployment Patterns

Single Instance (Development)

```yaml

docker-compose.dev.yml

version: '3.8' services: ben: build: . ports: - "5900:5900" volumes: - ./config.json:/app/config.json environment: - RUST_LOG=debug ```

High Availability (Production)

```yaml

docker-compose.prod.yml

version: '3.8' services: ben: image: danielsarmiento04/ben:latest deploy: replicas: 3 resources: limits: cpus: '0.5' memory: 128M volumes: - ./config.json:/app/config.json:ro environment: - RUSTLOG=info - BENWORKER_THREADS=4 ```

Kubernetes Deployment

yaml apiVersion: apps/v1 kind: Deployment metadata: name: ben-gateway spec: replicas: 3 selector: matchLabels: app: ben template: metadata: labels: app: ben spec: containers: - name: ben image: danielsarmiento04/ben:latest ports: - containerPort: 5900 resources: requests: memory: "64Mi" cpu: "100m" limits: memory: "128Mi" cpu: "500m" volumeMounts: - name: config mountPath: /app/config.json subPath: config.json volumes: - name: config configMap: name: ben-config

🚀 Quick Start

Get Ben up and running in under 2 minutes:

Option 1: Using Cargo

```bash

Install from crates.io

cargo install ben

Run with default configuration

ben ```

Option 2: From Source

```bash

Clone and build

git clone https://github.com/DanielSarmiento04/Ben.git cd Ben cargo run --release ```

Option 3: Using Docker

```bash

Pull and run

docker run -p 5900:5900 -v $(pwd)/config.json:/app/config.json danielsarmiento04/ben

Or build locally

docker build -t ben . docker run -p 5900:5900 ben ```

The service starts on http://localhost:5900 and is ready to handle requests!

🛠️ Examples

Basic Route Configuration

Create a config.json file to define your routing rules:

json { "version": 1, "routers": [ { "host": "http://api.internal.com", "port": 8080, "external_path": "/api/v1/users/{user_id}", "internal_path": "/users/{user_id}/profile", "methods": ["GET", "PUT", "DELETE"] }, { "host": "https://auth-service.com", "port": 443, "external_path": "/auth/login", "internal_path": "/v2/authenticate", "methods": ["POST"] }, { "host": "http://localhost", "port": 3000, "external_path": "/health", "internal_path": "/status/health", "methods": ["GET"] } ] }

Dynamic Path Parameters

Ben supports dynamic path parameters that are automatically extracted and forwarded:

json { "host": "http://backend.service.com", "port": 8080, "external_path": "/api/orders/{order_id}/items/{item_id}", "internal_path": "/orders/{order_id}/items/{item_id}/details", "methods": ["GET", "PUT", "DELETE"] }

Request Flow: ```bash

Client request

curl http://localhost:5900/api/orders/12345/items/67890

Gets routed to

curl http://backend.service.com:8080/orders/12345/items/67890/details ```

Real-World Usage Examples

API Gateway Setup

```bash

Route API calls to microservices

curl -X GET http://localhost:5900/api/v1/users/123

→ Forwards to: http://user-service:8080/users/123/profile

curl -X POST http://localhost:5900/auth/login -d '{"user":"john","pass":"secret"}'

→ Forwards to: https://auth-service.com:443/v2/authenticate

```

Load Balancing with Health Checks

```bash

Health check endpoint

curl http://localhost:5900/health

→ Forwards to: http://localhost:3000/status/health

```

📖 Documentation

Configuration Reference

Route Configuration Schema

| Field | Type | Required | Description | Example | |-------|------|----------|-------------|---------| | host | string | ✅ | Target service hostname with protocol | "http://api.service.com" | | port | number | ✅ | Target service port | 8080 | | external_path | string | ✅ | Incoming request path pattern | "/api/users/{id}" | | internal_path | string | ✅ | Target service path template | "/users/{id}/profile" | | methods | string[] | ✅ | Allowed HTTP methods | ["GET", "POST", "PUT"] |

Path Parameter Syntax

Ben supports dynamic path parameters using curly brace syntax:

  • {id} - Matches any non-slash characters
  • {user_id} - Parameter names can include underscores
  • {product_id} - Multiple parameters per route supported

Pattern Examples: /users/{id} → /users/123 /api/v1/orders/{order_id}/items/{id} → /api/v1/orders/456/items/789 /files/{path} → /files/documents/report.pdf

Environment Variables

Configure Ben using environment variables:

```bash

Server configuration

export BENHOST="0.0.0.0" # Bind address (default: 0.0.0.0) export BENPORT="5900" # Server port (default: 5900) export BENCONFIGPATH="./config.json" # Config file path

Performance tuning

export BENWORKERTHREADS="4" # Worker thread count export BENREQUESTTIMEOUT="30" # Request timeout in seconds export BENCONNECTIONPOOL_SIZE="32" # Connection pool size

Logging configuration

export RUSTLOG="ben=info" # Log level export BENLOGFORMAT="json" # Log format: json|pretty export NOCOLOR="1" # Disable colored output ```

Performance Tuning

Connection Pooling

rust // Default configuration provides optimal performance // Connection pool: 32 idle connections per host // Pool timeout: 30 seconds // Keep-alive: Enabled with 30s timeout

Async Configuration

```bash

Optimize for your workload

export TOKIOWORKERTHREADS=8 # CPU-bound tasks export BENMAXCONCURRENT_REQUESTS=1000 # Concurrent request limit ```

🔧 API Reference

Health and Monitoring

Ben provides built-in endpoints for monitoring and health checks:

```bash

Health check (if configured in routes)

GET /health

Response: 200 OK with upstream health status

Metrics endpoint (built-in)

GET /_ben/metrics

Response: Prometheus-compatible metrics

Status endpoint (built-in)

GET /_ben/status

Response: Service status and route information

```

Error Responses

Ben returns structured error responses with consistent format:

json { "error": "Request timeout", "type": "timeout", "timestamp": "2024-09-10T14:30:15Z", "request_id": "req_123456789" }

HTTP Status Codes

| Status | Error Type | Description | Retry | |--------|------------|-------------|-------| | 404 | not_found | No matching route found | ❌ | | 405 | method_not_allowed | HTTP method not allowed for route | ❌ | | 502 | bad_gateway | Upstream service error | ✅ | | 504 | gateway_timeout | Request timeout (30s default) | ✅ | | 500 | internal_error | Internal server error | ✅ |

Request/Response Headers

Ben forwards most headers between client and upstream service:

Forwarded Headers

```http

Client → Ben → Upstream

Authorization: Bearer Content-Type: application/json User-Agent: MyApp/1.0 X-Request-ID: req_123 ```

Added Headers

```http

Ben → Upstream

X-Forwarded-For: X-Forwarded-Proto: X-Forwarded-Host: X-Ben-Version: 0.1.0 ```

Blocked Headers

Ben filters out connection-specific headers: - Connection - Host (replaced with target host) - Upgrade - Proxy-*

📝 Logging and Observability

Ben features enterprise-grade logging and observability built for production environments.

Structured Logging

```bash

JSON format (production)

{"timestamp":"2024-09-10T14:30:15Z","level":"INFO","target":"ben::routes","message":"Request forwarded","requestid":"req123","duration_ms":45}

Pretty format (development)

Sep 10 02:30:15 PM | [INFO] | ben::routes | Request forwarded | reqid=req123 duration=45ms ```

Log Levels and Configuration

```bash

Environment-based configuration

export RUSTLOG="ben=info" # Application logs export RUSTLOG="ben=debug,actixweb=warn" # Detailed app logs, minimal framework logs export RUSTLOG="trace" # Everything (debug only!)

Structured logging

export BENLOGFORMAT="json" # json|pretty|compact export BENLOGTIMESTAMP="rfc3339" # rfc3339|unix|none ```

Monitoring and Metrics

Ben exposes comprehensive metrics for production monitoring:

Request Metrics

  • Request count by route and status code
  • Request duration histograms
  • Active connection count
  • Error rate by upstream service

System Metrics

  • Memory usage and GC statistics
  • CPU utilization per worker thread
  • Connection pool utilization
  • Upstream service health status

Custom Metrics Integration

```bash

Prometheus scraping endpoint

curl http://localhost:5900/_ben/metrics

Example metrics output

benrequeststotal{route="/api/users/{id}",method="GET",status="200"} 1234 benrequestdurationseconds{route="/api/users/{id}",method="GET"} 0.045 benupstream_health{service="user-service"} 1 ```

Distributed Tracing

Enable distributed tracing with OpenTelemetry:

```bash

Jaeger integration

export OTELEXPORTERJAEGERENDPOINT="http://jaeger:14268/api/traces" export OTELSERVICENAME="ben-gateway" export OTELTRACESAMPLER="parentbasedtraceidratio" export OTELTRACESAMPLER_ARG="0.1" # 10% sampling rate ```

🛠️ Development Guide

Prerequisites

Development Setup

```bash

Clone repository

git clone https://github.com/DanielSarmiento04/Ben.git cd Ben

Install development dependencies

cargo install cargo-watch cargo-audit cargo-tarpaulin

Run in development mode with hot reload

cargo watch -x run

Run tests with coverage

cargo tarpaulin --out html --output-dir coverage ```

Project Architecture

``` src/ ├── main.rs # Application entry point and server setup ├── lib.rs # Library root for integration testing ├── config/ │ ├── mod.rs # Configuration module exports │ └── settings.rs # Configuration loading and validation ├── models/ │ ├── mod.rs # Model module exports
│ ├── router.rs # Route definitions and validation │ ├── settings.rs # Settings data structures │ └── error.rs # Error types and HTTP mapping ├── routes/ │ ├── mod.rs # Route module exports │ ├── http.rs # HTTP route configuration │ └── websocket.rs # WebSocket routes (future feature) ├── services/ │ ├── mod.rs # Service module exports │ └── http.rs # Core HTTP handling and forwarding ├── utils/ │ ├── mod.rs # Utility module exports │ ├── path.rs # Path formatting utilities │ └── route_matcher.rs # High-performance route matching engine └── logs/ ├── mod.rs # Logging module exports └── logger.rs # Custom logger implementation

tests/ └── routematchertests.rs # Integration tests for route matching

docs/ ├── ROUTEMATCHINGGUIDE.md # Detailed route matching documentation └── CLEANUP_SUMMARY.md # Code cleanup and best practices ```

Development Commands

```bash

Code quality and testing

cargo fmt # Format code cargo clippy # Lint code cargo test # Run all tests cargo test --test routematchertests # Run specific integration tests cargo bench # Run performance benchmarks

Security and auditing

cargo audit # Security vulnerability scan cargo deny check # License and dependency checks cargo outdated # Check for outdated dependencies

Release preparation

cargo build --release # Optimized build cargo doc --open # Generate and open documentation ```

Testing Strategy

Unit Tests

```bash

Run unit tests only

cargo test --lib

Test specific modules

cargo test utils::route_matcher ```

Integration Tests

```bash

Run integration tests

cargo test --test '*'

Performance tests with output

cargo test performance_tests -- --nocapture ```

Load Testing

```bash

Install and run load tests

cargo install drill drill --benchmark drill.yml --stats ```

Code Quality Standards

Formatting and Linting

```toml

.rustfmt.toml

edition = "2021" maxwidth = 100 hardtabs = false tabspaces = 4 usesmall_heuristics = "Max" ```

Clippy Configuration

```toml

Cargo.toml

[lints.clippy] pedantic = "warn" nursery = "warn" unwrapused = "deny" expectused = "deny" ```

Technology Stack

| Component | Technology | Version | Purpose | |-----------|------------|---------|---------| | Web Framework | Actix Web | 4.x | High-performance async web server | | HTTP Client | Reqwest | 0.12 | Feature-rich HTTP client with connection pooling | | Async Runtime | Tokio | 1.x | Asynchronous runtime for Rust | | Serialization | Serde | 1.0 | JSON/YAML serialization framework | | Logging | Log + env_logger | 0.4 + 0.11 | Structured logging with color support | | Error Handling | thiserror | 1.0 | Ergonomic error type derivation | | Pattern Matching | Regex | 1.11 | High-performance regex engine | | Date/Time | Chrono | 0.4 | Date and time library |

Performance Characteristics

Benchmarks (on Apple M1 Pro)

| Metric | Value | Conditions | |--------|-------|------------| | Requests/sec | 45,000+ | Static route matching | | Latency P50 | 0.8ms | Dynamic route matching |
| Latency P99 | 2.1ms | Complex multi-parameter routes | | Memory Usage | ~15MB | Idle with 100 routes loaded | | CPU Usage | ~5% | Under moderate load (1000 req/s) |

Load Testing Results

```bash

Static routes performance

Static route matching: 10000 iterations in 22ms

Result: ~454,545 operations/second

Dynamic routes performance

Dynamic route matching: 10000 iterations in 48ms

Result: ~208,333 operations/second

Complex patterns performance

Complex pattern matching: 10000 iterations in 87ms

Result: ~114,942 operations/second

```

Docker Support

Multi-stage Dockerfile

```dockerfile

Production-optimized image ~15MB

FROM rust:1.70-alpine AS builder

... build steps ...

FROM alpine:latest RUN apk --no-cache add ca-certificates COPY --from=builder /app/target/release/ben /usr/local/bin/ben CMD ["ben"] ```

Docker Compose

yaml version: '3.8' services: ben: image: danielsarmiento04/ben:latest ports: - "5900:5900" volumes: - ./config.json:/app/config.json:ro environment: - RUST_LOG=ben=info - BEN_WORKER_THREADS=4 restart: unless-stopped

🤝 Contributing

We welcome contributions! Ben follows standard open-source practices and maintains high code quality standards.

How to Contribute

  1. Fork the Repository ```bash

    Fork on GitHub, then clone your fork

    git clone https://github.com/YOUR_USERNAME/Ben.git cd Ben ```

  2. Set Up Development Environment ```bash

    Install development tools

    rustup component add rustfmt clippy cargo install cargo-watch cargo-audit

# Verify setup cargo test cargo clippy ```

  1. Create a Feature Branch ```bash git checkout -b feature/amazing-feature

    or

    git checkout -b fix/important-bug ```

  2. Make Your Changes

    • Write code following our style guide
    • Add tests for new functionality
    • Update documentation as needed
    • Ensure all tests pass
  3. Submit a Pull Request bash git add . git commit -m "feat: add amazing feature" git push origin feature/amazing-feature

Code Style Guide

Rust Conventions

```rust // Use descriptive names pub struct RouteMatchError { // Fields should be private unless needed message: String, }

// Comprehensive error handling pub fn findroute(&self, path: &str) -> Result { // No unwrap() or expect() in production code self.routes.get(path) .okorelse(|| RouteMatchError::NotFound { path: path.tostring() }) }

// Document public APIs /// Finds a matching route for the given request path. /// /// # Arguments /// * path - The incoming request path to match /// /// # Returns /// Returns the matched route and transformed internal path, or an error if no match found. /// /// # Examples /// /// let matcher = RouteMatcher::new(routes)?; /// let (route, internal_path) = matcher.find_match("/api/users/123")?; /// pub fn find_match(&self, path: &str) -> Result<(Router, String), RouteMatchError> { // Implementation... } ```

Commit Message Format

```bash

Format: type(scope): description

feat(router): add dynamic path parameter support fix(http): handle connection timeout errors properly
docs(readme): update installation instructions test(routes): add integration tests for edge cases refactor(matcher): optimize regex compilation performance ```

Types of Contributions

🐛 Bug Reports

  • Use the bug report template
  • Provide minimal reproduction case
  • Include system information and logs

✨ Feature Requests

  • Use the feature request template
  • Explain the use case and benefits
  • Consider backwards compatibility

📖 Documentation

  • Fix typos and improve clarity
  • Add examples and tutorials
  • Update API documentation

🧪 Testing

  • Increase test coverage
  • Add performance benchmarks
  • Improve integration tests

🔧 Performance

  • Profile and optimize hot paths
  • Reduce memory allocations
  • Improve async performance

Development Workflow

Before Submitting

```bash

Required checks (automated in CI)

cargo fmt --check # Code formatting cargo clippy -- -D warnings # Linting with warnings as errors cargo test # All tests pass cargo audit # Security audit cargo doc --no-deps # Documentation builds

Performance regression check

cargo test performance_tests -- --nocapture ```

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

Special thanks to the amazing Rust community and the following projects that make Ben possible:

  • Actix Web - For the high-performance web framework
  • Tokio - For the excellent async runtime
  • Serde - For seamless serialization
  • Reqwest - For the robust HTTP client
  • Rust Community - For continuous inspiration and support

📊 Project Stats

![GitHub stars](https://img.shields.io/github/stars/DanielSarmiento04/Ben?style=social) ![GitHub forks](https://img.shields.io/github/forks/DanielSarmiento04/Ben?style=social) ![GitHub issues](https://img.shields.io/github/issues/DanielSarmiento04/Ben) ![GitHub pull requests](https://img.shields.io/github/issues-pr/DanielSarmiento04/Ben)

🔗 Related Projects

  • Nginx - High-performance web server and reverse proxy
  • HAProxy - Reliable, high-performance load balancer
  • Traefik - Modern reverse proxy with automatic service discovery
  • Envoy - Cloud-native high-performance proxy

**[⭐ Star this project](https://github.com/DanielSarmiento04/Ben)** • **[📖 Documentation](https://github.com/DanielSarmiento04/Ben/wiki)** • **[🐛 Report Bug](https://github.com/DanielSarmiento04/Ben/issues)** • **[💡 Request Feature](https://github.com/DanielSarmiento04/Ben/issues)** Built with ❤️ and ⚡ by [Daniel Sarmiento](https://github.com/DanielSarmiento04) and [contributors](https://github.com/DanielSarmiento04/Ben/graphs/contributors)

Owner

  • Name: José Daniel Sarmiento
  • Login: DanielSarmiento04
  • Kind: user
  • Location: Santander, Colombia
  • Company: Axede S.A

Programmer, mechanical engineer and entrepreneur, my goal is to improve the quality of life of people, technology is the tool I use.

GitHub Events

Total
  • Watch event: 1
  • Push event: 12
  • Pull request event: 3
Last Year
  • Watch event: 1
  • Push event: 12
  • Pull request event: 3