Skip to content

TaranjyotS/distributed-api-gateway

Repository files navigation

🌐 Distributed API Gateway

Production-ready FastAPI gateway for service discovery, secure routing, API keys, rate limiting, caching, resilience, and observability.

Overview β€’ Features β€’ Screenshots β€’ Architecture β€’ Quick Start β€’ API Flow β€’ Observability β€’ Troubleshooting


πŸ“Œ Overview

Distributed API Gateway is a portfolio-grade platform engineering project that demonstrates how microservice organizations centralize traffic management, authentication, service discovery, request routing, reliability, and observability behind a single controlled entry point.

The project includes a real FastAPI gateway, PostgreSQL-backed service and route registry, Redis-backed rate limiting and caching, API-key and JWT authentication, retry handling, circuit breaker protection, audit logs, Prometheus metrics, Grafana dashboards, Docker Compose, Kubernetes manifests, GitHub Actions, Jenkins, and a bundled mock downstream microservice for end-to-end validation.


✨ Features

🧭 Gateway Core

  • Dynamic /gateway/{path} proxying
  • PostgreSQL service registry
  • Route registry and matching
  • Path prefix mapping
  • Mock downstream microservice
  • Swagger-documented APIs

πŸ” Security

  • Admin API protection
  • API key authentication
  • Hashed API keys
  • JWT bearer token support
  • Client onboarding workflow
  • Request correlation IDs

βš™οΈ Reliability

  • Redis rate limiting
  • Redis response caching
  • Configurable retries
  • Circuit breaker pattern
  • Timeout handling
  • Audit logging

πŸ“Š Observability

  • Prometheus /metrics
  • Grafana provisioning
  • Request counters
  • Latency histograms
  • Rate limit metrics
  • Downstream error metrics

πŸš€ DevOps

  • Dockerfile
  • Docker Compose stack
  • Kubernetes manifests
  • GitHub Actions CI
  • Jenkinsfile
  • Environment config

πŸ§ͺ Quality

  • Unit tests
  • Integration-style tests
  • Ruff linting
  • Bandit scan
  • Coverage-ready setup
  • Production folder layout

🧱 Tech Stack


Python
Backend

FastAPI
Gateway + Mock Service

PostgreSQL
Registry + Audit Logs

Redis
Rate Limit + Cache

Docker
Containerization

Kubernetes
Deployment

Prometheus
Metrics

Grafana
Dashboards

GitHub Actions
CI/CD

Jenkins
Pipeline

AWS
Cloud Architecture

Bandit
DevSecOps

πŸ“Έ Screenshots

Dashboard

Swagger Endppints

Prometheus

Grafana


πŸ—οΈ Architecture

flowchart TD
    A[Client / API Consumer] --> B[FastAPI Distributed API Gateway]
    B --> C[Request Context Middleware]
    C --> D[Route Lookup]
    D --> E[(PostgreSQL Service + Route Registry)]
    D --> F[Authentication Layer]
    F --> G[API Key / JWT Validation]
    G --> H[Redis Rate Limiter]
    H --> I[Redis Cache]
    I --> J[Retry + Circuit Breaker]
    J --> K[Mock User Microservice]
    B --> L[(PostgreSQL Audit Logs)]
    B --> M[Prometheus Metrics]
    M --> N[Grafana Dashboard]
Loading

πŸ”„ Gateway Request Flow

Client sends request to /gateway/{path}
        ↓
Gateway normalizes incoming path
        ↓
Route registry resolves matching path_prefix and HTTP method
        ↓
If auth_required=true, gateway validates x-api-key or Authorization: Bearer token
        ↓
Redis enforces client + route rate limit
        ↓
Redis cache is checked for cacheable GET requests
        ↓
Gateway builds upstream URL using service.base_url + upstream_path_prefix + path suffix
        ↓
Request is proxied to the downstream service with timeout + retry handling
        ↓
Circuit breaker records success/failure
        ↓
Response is cached if eligible
        ↓
Audit log is written to PostgreSQL
        ↓
Prometheus metrics are updated
        ↓
Gateway returns downstream response to the client

Example Mapping

Gateway Request Route Config Downstream Call
GET /gateway/health path_prefix="", upstream_path_prefix="", method=ANY GET http://mock-user-service:9001/health
GET /gateway/health with valid x-api-key auth_required=true Gateway validates API key before proxying
GET /gateway/health repeated multiple times cache_enabled=true, cache_ttl_seconds=30 Response may be served from Redis cache

πŸ—„οΈ Database Design

erDiagram
    SERVICES ||--o{ ROUTES : owns
    CLIENTS ||--o{ API_KEYS : owns
    CLIENTS ||--o{ AUDIT_LOGS : generates

    SERVICES {
        string id
        string name
        string base_url
        string health_check_path
        string status
        datetime created_at
    }

    ROUTES {
        string id
        string service_id
        string path_prefix
        string upstream_path_prefix
        string method
        boolean auth_required
        boolean cache_enabled
        integer cache_ttl_seconds
        integer timeout_seconds
        integer retry_count
        integer circuit_failure_threshold
    }

    CLIENTS {
        string id
        string name
        string role
        boolean active
        datetime created_at
    }

    API_KEYS {
        string id
        string client_id
        string key_prefix
        string hashed_key
        boolean active
        datetime created_at
    }

    AUDIT_LOGS {
        string id
        string client_id
        string request_id
        string route
        string method
        integer status_code
        datetime created_at
    }
Loading

⚑ Quick Start

Prerequisites

Requirement Version
Docker Desktop Latest stable
Python 3.11+
Git Any recent version

Run the Full Stack

cp .env.example .env
docker compose down -v --remove-orphans
docker compose up --build

Open:

Gateway Console:   http://localhost:8000/dashboard
Swagger API Docs:  http://localhost:8000/docs
Health Check:      http://localhost:8000/health
Mock Service:      http://localhost:8081/health
Prometheus:        http://localhost:9090
Grafana:           http://localhost:3000

Grafana login:

admin / admin

πŸ”Œ API Flow

Option A: Bootstrap the Full Demo

bash sample-data/bootstrap.sh

The script creates:

  • downstream service registry entry
  • authenticated /users gateway route
  • demo client
  • API key
  • first successful /gateway/users request

Then generate more traffic:

export API_KEY="PASTE_GENERATED_API_KEY"
bash sample-data/generate-traffic.sh

Option B: Manual Flow

1. Register the mock downstream service

curl -X POST http://localhost:8000/admin/services \
  -H "x-admin-key: dev-admin-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "mock-user-service",
    "base_url": "http://mock-user-service:9001",
    "health_check_path": "/health"
  }'

2. Create a gateway route

Use the returned service ID from step 1.

curl -X POST http://localhost:8000/admin/routes \
  -H "x-admin-key: dev-admin-key" \
  -H "Content-Type: application/json" \
  -d '{
    "service_id": "SERVICE_ID",
    "path_prefix": "/users",
    "upstream_path_prefix": "/users",
    "method": "ANY",
    "auth_required": true,
    "cache_enabled": true,
    "cache_ttl_seconds": 30,
    "timeout_seconds": 3,
    "retry_count": 1,
    "circuit_failure_threshold": 3
  }'

3. Create a client

curl -X POST http://localhost:8000/admin/clients \
  -H "x-admin-key: dev-admin-key" \
  -H "Content-Type: application/json" \
  -d '{"name":"demo-client","role":"consumer"}'

4. Generate an API key

curl -X POST http://localhost:8000/admin/api-keys \
  -H "x-admin-key: dev-admin-key" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"CLIENT_ID"}'

Store the returned api_key. It is shown only once.

5. Call the gateway

curl -X GET http://localhost:8000/gateway/users \
  -H "x-api-key: YOUR_GENERATED_API_KEY"

Expected response:

{
  "service": "mock-user-service",
  "data": [
    {"id": "usr_001", "name": "Ava Patel", "role": "consumer"},
    {"id": "usr_002", "name": "Noah Singh", "role": "admin"}
  ]
}

Swagger Note

The gateway endpoints expose x-api-key and Authorization header fields directly in Swagger.

When testing /gateway/{path} in Swagger, enter the path without the leading slash:

users

Do not enter:

/users

Swagger encodes a leading slash as %2F, which changes the route path.


πŸ“Š Observability

Prometheus

Open:

http://localhost:9090/targets

The target should be:

http://gateway:8000/metrics  UP

Important: gateway:8000 is a Docker-internal hostname. It works from Prometheus inside Docker, but not from your browser on the host machine. In your browser, use:

http://localhost:8000/metrics

Useful Prometheus queries:

gateway_requests_total
rate(gateway_requests_total[5m])
sum(rate(gateway_requests_total[1m]))
histogram_quantile(0.95, sum(rate(gateway_request_latency_seconds_bucket[5m])) by (le))
gateway_cache_events_total
gateway_rate_limit_blocks_total
gateway_downstream_errors_total

Grafana

Open:

http://localhost:3000

Then go to:

Dashboards β†’ API Gateway β†’ Distributed API Gateway Overview

Some panels may show No data until the related event actually happens:

Panel Why It May Be Empty How to Generate Data
Gateway Requests No traffic yet Call /health, /ready, /gateway/users
Latency p95 Not enough traffic yet Run repeated requests
Rate Limit Blocks Limit has not been exceeded Send more requests than the route limit
Downstream Errors Mock service is healthy Stop mock service or route to invalid upstream

Generate traffic:

export API_KEY="PASTE_GENERATED_API_KEY"
bash sample-data/generate-traffic.sh

πŸ§ͺ Testing and Quality Gates

pip install -r requirements.txt
pytest
coverage run -m pytest && coverage report
ruff check app tests
bandit -r app -x tests

Validated quality checks:

pytest: passing
ruff: passing
bandit: passing

🚒 Deployment

Docker Compose

docker compose up --build

Kubernetes

kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secret.example.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/hpa.yaml

AWS Reference Architecture

Route 53 / CloudFront / ALB
        ↓
AWS EKS or ECS Fargate
        ↓
Distributed API Gateway Pods
        ↓
Amazon RDS PostgreSQL
Amazon ElastiCache Redis
Amazon ECR
CloudWatch Logs
Prometheus + Grafana
AWS Secrets Manager

πŸ›‘οΈ Security Design

Included

  • Admin API protection
  • API key authentication
  • API key hashing
  • JWT bearer support
  • Environment-based secrets
  • Pydantic validation
  • Bandit security scan
  • Request correlation IDs
  • No committed real secrets

Production Enhancements

  • AWS Secrets Manager
  • TLS termination at ALB/API Gateway
  • WAF rules
  • OAuth2/OIDC integration
  • Redis-backed distributed circuit breaker
  • OpenTelemetry traces
  • Centralized SIEM logging
  • mTLS for internal services

🧠 What This Project Demonstrates

Skill Area Demonstrated Through
Backend Engineering FastAPI routing, middleware, proxying, validation
Distributed Systems Gateway routing, retries, circuit breaker, rate limiting
Platform Engineering Service registry, route registry, client onboarding
Security Engineering API keys, JWT, admin controls, hashed secrets
Data Engineering PostgreSQL schema, audit logs, operational data model
DevOps Docker, Kubernetes, GitHub Actions, Jenkins
Observability Prometheus metrics, Grafana dashboard, request IDs
Cloud Architecture AWS-ready deployment design with RDS and ElastiCache
Testing Unit and integration-style gateway tests

πŸ“ Folder Structure
distributed-api-gateway/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ api/                    # health, auth, admin, gateway routes
β”‚   β”œβ”€β”€ core/                   # config, security, metrics, logging
β”‚   β”œβ”€β”€ db/                     # SQLAlchemy session/bootstrap
β”‚   β”œβ”€β”€ middleware/             # request context + metrics middleware
β”‚   β”œβ”€β”€ models/                 # database entities
β”‚   β”œβ”€β”€ schemas/                # Pydantic DTOs
β”‚   β”œβ”€β”€ services/               # router, Redis, rate limiter, circuit breaker
β”‚   └── main.py                 # FastAPI app + dashboard
β”œβ”€β”€ mock_services/              # downstream user microservice for demo traffic
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ screenshots/            # README screenshots
β”‚   β”œβ”€β”€ api-spec.md
β”‚   β”œβ”€β”€ aws-architecture.md
β”‚   └── security.md
β”œβ”€β”€ k8s/                        # Kubernetes manifests
β”œβ”€β”€ monitoring/                 # Prometheus + Grafana provisioning
β”œβ”€β”€ sample-data/                # bootstrap and traffic scripts
β”œβ”€β”€ tests/                      # unit and integration-style tests
β”œβ”€β”€ .github/workflows/ci.yml    # GitHub Actions pipeline
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ Jenkinsfile
β”œβ”€β”€ Makefile
β”œβ”€β”€ requirements.txt
└── README.md

🧰 Troubleshooting

Gateway returns Example Domain or 404 from Cloudflare

That means the gateway is working but the registered service points to https://example.com or another placeholder upstream.

Register the included Docker Compose mock service instead:

{
  "name": "mock-user-service",
  "base_url": "http://mock-user-service:9001",
  "health_check_path": "/health"
}

Then create a route with:

{
  "path_prefix": "/users",
  "upstream_path_prefix": "/users",
  "method": "ANY"
}
Swagger gateway route says β€œValid API key or JWT required”

The route requires authentication.

Use the x-api-key field shown in the Swagger gateway endpoint after clicking Try it out.

Also enter the path without a leading slash:

users

Not:

/users
I clicked Prometheus target `gateway:8000` and browser cannot open it

That is expected.

gateway is a Docker Compose service name and only resolves inside the Docker network.

Use this in your browser instead:

http://localhost:8000/metrics
Grafana shows No data

Generate traffic first:

export API_KEY="PASTE_GENERATED_API_KEY"
bash sample-data/generate-traffic.sh

Rate-limit and downstream-error panels remain empty until those events occur.

Docker Compose starts Prometheus/Grafana but not Swagger

Check gateway logs:

docker compose logs gateway

Then restart cleanly:

docker compose down -v --remove-orphans
docker compose up --build
PostgreSQL or Redis connection errors on startup

The app includes startup retries, but a clean volume reset usually fixes stale local state:

docker compose down -v --remove-orphans
docker compose up --build

πŸ—ΊοΈ Roadmap

Priority Improvement
High Add OpenTelemetry distributed tracing
High Add Redis-backed distributed circuit breaker state
High Add OAuth2/OIDC identity provider integration
Medium Add admin dashboard CRUD controls for services/routes
Medium Add per-client quota policies
Medium Add route-level transformation plugins
Medium Add service health polling and automatic status updates
Low Add Terraform AWS deployment module
Low Add canary deployment strategy

πŸ“„ License

This project is licensed under the MIT License.


⚠️ Disclaimer

This project is built for portfolio, learning, and authorized internal platform engineering use cases.

Do not expose development credentials, local API keys, or test secrets in public environments.

About

Production-grade distributed API gateway built with FastAPI, PostgreSQL, Redis, Docker, Kubernetes, Prometheus, and Grafana, featuring service discovery, API keys, JWT auth, rate limiting, caching, retries, circuit breaking, and observability.

Topics

Resources

License

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors