Skip to content

menta2k/gproxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GProxy - Google Maps API Caching Proxy

A high-performance, intelligent caching proxy for Google Maps APIs built in Rust. GProxy sits between your applications and Google Maps APIs, providing Redis-based caching, retry logic, and cost optimization through intelligent response caching.

πŸš€ Features

Core Functionality

  • πŸ—ΊοΈ Google Maps API Proxy - Supports Geocoding, Directions, Distance Matrix, and Places APIs
  • πŸš€ Redis Caching - Intelligent caching with configurable TTLs per API endpoint
  • πŸ”„ Smart Retry Logic - Exponential backoff with jitter for handling transient failures
  • πŸ’° Cost Optimization - Reduces Google Maps API calls through strategic caching
  • πŸ”’ TLS/HTTPS Support - Optional TLS configuration for secure communication
  • πŸ“Š Observability - Comprehensive tracing, metrics, and structured logging

Performance & Reliability

  • ⚑ Async/Await - Built on Tokio for high-performance async I/O
  • πŸ›‘οΈ Graceful Shutdown - Proper signal handling and connection draining
  • πŸ”§ Health Checks - Built-in health and readiness endpoints
  • 🌐 CORS Support - Configurable Cross-Origin Resource Sharing
  • πŸ“¦ Response Compression - Optional gzip/deflate compression

Compliance & Best Practices

  • πŸ“œ Google ToS Compliant - Respects Google's 30-day geocoding cache limit
  • πŸ”‘ Flexible API Key Handling - Supports both header-based and config-based API keys
  • 🏷️ Cache Headers - Provides cache status information in responses
  • πŸ“ˆ Rate Limit Aware - Intelligent handling of Google's rate limits

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Your App      │───▢│     GProxy      │───▢│  Google Maps    β”‚
β”‚                 β”‚    β”‚                 β”‚    β”‚      API        β”‚
β”‚                 │◀───│  Redis Cache    │◀───│                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

GProxy acts as an intelligent middleware that:

  1. Receives requests from your applications
  2. Checks Redis cache for existing responses
  3. On cache miss, forwards requests to Google Maps API
  4. Caches responses with appropriate TTLs
  5. Returns cached or fresh responses to clients

πŸ“¦ Installation

Prerequisites

  • Rust 1.70+
  • Redis server
  • Google Maps API key

From Source

git clone <repository-url>
cd gproxy
cargo build --release

Using Docker

# Build the image
docker build -t gproxy .

# Run with environment variables
docker run -d \
  -p 8080:8080 \
  -e GOOGLE_API_KEY=your_api_key \
  -e REDIS_HOST=redis_host \
  gproxy

βš™οΈ Configuration

GProxy is configured via environment variables:

Core Configuration

# Server Configuration
GPROXY_ADDRESS=0.0.0.0:8080           # Server bind address
GPROXY_TLS_PATH=/path/to/certs        # Optional TLS certificate path
GPROXY_OBS_ENDPOINT=http://jaeger:14268/api/traces  # Observability endpoint

# Google Maps API
GOOGLE_API_KEY=your_google_maps_api_key
GOOGLE_BASE_URL=https://maps.googleapis.com/maps/api
GOOGLE_TIMEOUT_MS=1000               # Request timeout (1s)
GOOGLE_MAX_RETRIES=3                  # Maximum retry attempts
GOOGLE_RATE_SEC=10                    # Rate limit per second

# Redis Configuration  
REDIS_HOST=127.0.0.1                 # Redis server host
REDIS_PORT=6379                       # Redis server port
REDIS_PREFIX=geo_cache                # Cache key prefix
REDIS_POOL_SIZE=10                    # Connection pool size
REDIS_TIMEOUT_MS=1000                 # Redis operation timeout

# Cache TTL Configuration (seconds)
GOOGLE_TLS_GEOCODE=2592000           # 30 days (Google ToS requirement)
GOOGLE_TLS_DIRECTIONS=3600           # 1 hour
GOOGLE_TLS_DISTANCE_MATRIX=3600      # 1 hour  
GOOGLE_TLS_PLACES=86400              # 24 hours
GOOGLE_TLS_DEFAULT=3600              # 1 hour

# Server Options
SERVER_ENABLE_COMPRESSION=true        # Enable gzip/deflate compression
SERVER_CORS_ORIGINS=*                # CORS origins (* for any)
SERVER_SHUTDOWN_TIMEOUT_SECS=30      # Graceful shutdown timeout

# Retry Configuration
GOOGLE_MAPS_MAX_RETRIES=3            # Maximum retry attempts
GOOGLE_MAPS_BASE_DELAY_MS=100        # Base retry delay
GOOGLE_MAPS_MAX_DELAY_MS=5000        # Maximum retry delay
GOOGLE_MAPS_EXPONENTIAL_BACKOFF=true # Use exponential backoff
GOOGLE_MAPS_USE_JITTER=true          # Add jitter to retries
GOOGLE_MAPS_JITTER_PERCENT=25        # Jitter percentage (Β±25%)
GOOGLE_MAPS_RETRY_ON_RATE_LIMIT=true # Retry on rate limit errors
GOOGLE_MAPS_RATE_LIMIT_DELAY_MS=1000 # Rate limit retry delay

πŸš€ Usage

Starting the Server

# Basic startup
./gproxy

# With custom configuration
GOOGLE_API_KEY=your_key REDIS_HOST=localhost ./gproxy

# With TLS
GPROXY_TLS_PATH=/etc/ssl/certs ./gproxy

# Custom bind address
GPROXY_ADDRESS=0.0.0.0:9000 ./gproxy

API Endpoints

Google Maps API Proxy

All Google Maps API endpoints are available under /maps/api/:

# Geocoding API
GET /maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA

# Directions API  
GET /maps/api/directions/json?origin=Toronto&destination=Montreal

# Distance Matrix API
GET /maps/api/distancematrix/json?origins=Vancouver+BC&destinations=Seattle

# Places API - Find Place
GET /maps/api/place/findplacefromtext/json?input=Museum+of+Contemporary+Art+Australia&inputtype=textquery

# Places API - Place Details
GET /maps/api/place/details/json?place_id=ChIJN1t_tDeuEmsRUsoyG83frY4

API Key Options

# Option 1: Use configured API key (from GOOGLE_API_KEY env var)
curl "http://localhost:8080/maps/api/geocode/json?address=Toronto"

# Option 2: Provide API key via header
curl -H "X-Maps-API-Key: your_api_key" \
     "http://localhost:8080/maps/api/geocode/json?address=Toronto"

Health & Monitoring Endpoints

# Health check (includes Redis connectivity)
GET /health

# Server information
GET /info

# Configuration dump
GET /config.json

Response Headers

GProxy adds helpful headers to responses:

HTTP/1.1 200 OK
Content-Type: application/json
X-Cache-Status: HIT|MISS|ERROR
X-Cache-Key: geo_cache:geocode:abc123...

πŸ”§ Development

Project Structure

gproxy/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main.rs           # Application entry point
β”‚   β”œβ”€β”€ config/           # Configuration management
β”‚   β”‚   β”œβ”€β”€ mod.rs        # CLI argument parsing
β”‚   β”‚   └── retry.rs      # Retry configuration
β”‚   └── server/           # Server implementation
β”‚       β”œβ”€β”€ mod.rs        # HTTP server & routing
β”‚       β”œβ”€β”€ google.rs     # Google Maps API handler
β”‚       └── service_state.rs # Service state management
β”œβ”€β”€ Cargo.toml            # Dependencies & metadata
└── build.rs              # Build script

Building

# Development build
cargo build

# Release build
cargo build --release

# Run tests
cargo test

# Run with cargo
cargo run -- --address 0.0.0.0:8080

Dependencies

  • axum - Web framework
  • tokio - Async runtime
  • fred - Redis client
  • reqwest - HTTP client
  • serde - Serialization
  • tracing - Structured logging
  • clap - CLI parsing

πŸ“Š Observability

Logging

GProxy uses structured logging with tracing:

# Set log level
RUST_LOG=info ./gproxy

# Detailed logging
RUST_LOG=debug ./gproxy

# Module-specific logging
RUST_LOG=gproxy=debug,fred=info ./gproxy

Metrics & Tracing

  • OpenTelemetry integration for distributed tracing
  • Automatic request/response metrics
  • Cache hit/miss ratios
  • Error rate monitoring
  • Response time tracking

Health Monitoring

# Basic health check
curl http://localhost:8080/health

# Response includes Redis connectivity status
{
  "server": "server-1", 
  "port": 8080,
  "status": "healthy"
}

πŸ”’ Security

TLS Configuration

# Place certificates in TLS path
/etc/ssl/certs/
β”œβ”€β”€ gproxy.crt           # Certificate file
└── gproxy.key           # Private key file

# Start with TLS
GPROXY_TLS_PATH=/etc/ssl/certs ./gproxy

API Key Security

  • API keys can be provided via headers (recommended for multi-tenant scenarios)
  • Environment variable configuration for single-tenant deployments
  • No API keys are logged or exposed in responses

CORS Configuration

# Allow specific origins
SERVER_CORS_ORIGINS=https://yourdomain.com,https://app.yourdomain.com

# Allow any origin (development only)
SERVER_CORS_ORIGINS=*

🐳 Docker Deployment

Docker Compose Example

version: '3.8'
services:
  gproxy:
    build: .
    ports:
      - "8080:8080"
    environment:
      - GOOGLE_API_KEY=your_api_key
      - REDIS_HOST=redis
      - RUST_LOG=info
    depends_on:
      - redis
      
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data

volumes:
  redis_data:

πŸ› οΈ Troubleshooting

Common Issues

Connection Errors

# Check Redis connectivity
redis-cli -h $REDIS_HOST ping

# Verify Google API key
curl "https://maps.googleapis.com/maps/api/geocode/json?address=Toronto&key=$GOOGLE_API_KEY"

Cache Issues

# Check Redis keys
redis-cli keys "geo_cache:*"

# Clear cache
redis-cli flushdb

Performance Tuning

# Increase Redis pool size for high traffic
REDIS_POOL_SIZE=20

# Adjust retry settings
GOOGLE_MAPS_MAX_RETRIES=5
GOOGLE_MAPS_MAX_DELAY_MS=10000

# Enable compression for large responses
SERVER_ENABLE_COMPRESSION=true

Logging Debug Information

# Enable debug logging
RUST_LOG=debug ./gproxy

# Focus on specific modules
RUST_LOG=gproxy::server::google=trace,fred=debug ./gproxy

πŸ“‹ API Compliance

Google Maps Terms of Service

GProxy respects Google's Terms of Service:

  • Geocoding Cache Limit: 30 days maximum (configurable via GOOGLE_TLS_GEOCODE)
  • Attribution: Responses maintain original Google attribution
  • Rate Limiting: Intelligent retry handling respects API quotas
  • Terms Compliance: No modification of response data

Cache Behavior

  • Cache Keys: Generated using secure hashing of request parameters
  • TTL Enforcement: Automatic expiration based on Google's requirements
  • Cache Headers: Clear indication of cache status in responses
  • Selective Caching: Only successful responses are cached

πŸ“„ License

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

πŸ™ Acknowledgments

  • Google Maps Platform - For providing the underlying mapping APIs
  • Rust Community - For the excellent ecosystem of crates
  • Redis - For reliable caching infrastructure

GProxy - Making Google Maps APIs faster, cheaper, and more reliable! πŸ—ΊοΈβš‘

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published