Skip to content

devloopcode/api-gateway

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

API Gateway

API Gateway written in Go. Built with clean architecture principles, it sits in front of multiple microservices and handles cross-cutting concerns uniformly.

Features

Category Capabilities
Proxy Reverse proxy, path-based routing, header forwarding, WebSocket proxying
Auth JWT (HS256), API key (Redis-backed), per-service RBAC
Rate Limiting Redis sliding window — IP-based & user-based, per-service limits
Load Balancing Round robin, least connections, weighted round robin (Nginx smooth algo)
Resilience Circuit breakers (gobreaker), retry with exponential backoff, health recovery
Caching Redis response cache, SHA-256 keyed, configurable TTL per service
Observability Prometheus metrics, OpenTelemetry distributed tracing (OTLP), structured Zap logs
Security Secure headers (HSTS, CSP, XFO), CORS, request ID propagation
Operations Graceful shutdown, health + readiness probes, Docker, Docker Compose, Grafana

Architecture

cmd/gateway/          ← Entry point, wiring
internal/
  config/             ← Viper-based typed config
  domain/             ← Pure models & sentinel errors
  auth/               ← JWT + API key providers
  ratelimit/          ← Redis sliding window limiter
  cache/              ← Redis response cache
  loadbalancer/       ← RR / LC / WRR strategies
  circuitbreaker/     ← gobreaker wrapper
  registry/           ← In-memory service registry
  proxy/              ← httputil.ReverseProxy + retry
  observability/      ← Prometheus metrics + OTEL tracing
  middleware/         ← Gin middleware chain
  handlers/           ← Health, admin API
  router/             ← Route registration
  server/             ← http.Server + graceful shutdown
pkg/
  logger/             ← Zap factory
  redis/              ← go-redis client factory
configs/              ← config.yaml
deployments/          ← Dockerfile, Docker Compose, Prometheus, Grafana
tests/
  unit/               ← Load balancer, auth, circuit breaker tests
  integration/        ← Full gateway HTTP tests

Request Flow

Client Request
    │
    ▼
[RequestID] → [CORS] → [SecurityHeaders] → [Logger] → [Tracing] → [Metrics]
    │
    ▼
Router (prefix matching)
    │
    ├─ /health, /ready, /metrics, /admin/*
    │
    └─ /api/v1/{service}/*
            │
            ▼
        [Per-service Auth] → [Rate Limit] → [Cache Lookup]
            │                                   │
            │                             cache HIT → return
            │
            ▼
        Load Balancer → Select Backend
            │
            ▼
        Circuit Breaker → Retry (exponential backoff)
            │
            ▼
        httputil.ReverseProxy → Upstream Backend
            │
            ▼
        Cache Store (on success)
            │
            ▼
        Response to Client

Quick Start

Prerequisites

  • Go 1.22+
  • Redis 7+
  • Docker & Docker Compose (optional)

Run locally

# 1. Clone and install dependencies
git clone <repo>
cd api-gateway
go mod tidy

# 2. Start Redis
docker run -d -p 6379:6379 redis:7.2-alpine

# 3. Copy and edit config
cp .env.example .env
# Edit configs/config.yaml to add your upstream services

# 4. Run
make run

Run with Docker Compose (full stack)

# Starts: gateway, Redis, Prometheus, Grafana, Jaeger, echo backend
make docker-up

# View logs
make docker-logs

URLs:

Service URL
Gateway http://localhost:8080
Prometheus http://localhost:9090
Grafana http://localhost:3000 (admin/admin)
Jaeger UI http://localhost:16686

Configuration

config.yaml

All fields support environment variable overrides using SECTION_KEY format (dots → underscores).

server:
  port: 8080

services:
  - name: "my-service"
    prefix: "/api/v1/my-service"
    backends:
      - url: "http://my-service:3000"
        weight: 1
    load_balancer: "round_robin"   # round_robin | least_connections | weighted_round_robin
    auth:
      required: true
      type: "jwt"                  # jwt | api_key | any
      roles: ["admin"]             # optional RBAC
    rate_limit:
      enabled: true
      requests_per_second: 100
      burst: 200
    cache:
      enabled: true
      ttl: 5m
      methods: ["GET"]
    circuit_breaker:
      enabled: true
    retry:
      enabled: true
      max_attempts: 3
      backoff: 100ms
    timeout: 30s

Environment Variables

Variable Default Description
SERVER_PORT 8080 Listening port
REDIS_ADDR localhost:6379 Redis address
AUTH_JWT_SECRET JWT signing secret (required)
AUTH_JWT_ISSUER api-gateway JWT issuer claim
LOGGING_LEVEL info debug / info / warn / error
OBSERVABILITY_TRACING_ENDPOINT OTLP HTTP endpoint

See .env.example for the full list.


API

Gateway Endpoints

Method Path Description
GET /health Liveness probe
GET /ready Readiness probe (checks Redis)
GET /metrics Prometheus metrics

Admin API

Method Path Description
GET /admin/services List all registered services
GET /admin/services/:name Get service details
POST /admin/services Dynamically register a service
DELETE /admin/services/:name Deregister a service
GET /admin/circuit-breakers Circuit breaker states

Register a service dynamically

curl -X POST http://localhost:8080/admin/services \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-new-service",
    "prefix": "/api/v1/new",
    "backends": [{"url": "http://new-svc:3000", "weight": 1}],
    "load_balancer": "round_robin",
    "auth": {"required": false},
    "timeout": "30s"
  }'

Authentication

JWT

# Include in Authorization header
curl -H "Authorization: Bearer <token>" http://localhost:8080/api/v1/users/me

API Key

# Seed a key
redis-cli SET "apikey:my-key" '{"user_id":"u1","email":"u@e.com","roles":["developer"]}' EX 86400

# Use it
curl -H "X-API-Key: my-key" http://localhost:8080/api/v1/products

Observability

Prometheus Metrics

Metric Type Labels
gateway_requests_total Counter method, service, status
gateway_request_duration_seconds Histogram method, service
gateway_upstream_requests_total Counter service, backend, status
gateway_upstream_duration_seconds Histogram service
gateway_active_connections Gauge
gateway_cache_operations_total Counter service, result (hit/miss)
gateway_rate_limit_total Counter service
gateway_circuit_breaker_state Gauge service (0=closed, 1=half-open, 2=open)

Distributed Tracing

Configure the OTLP endpoint to send traces to Jaeger, Tempo, or any OpenTelemetry-compatible backend.

observability:
  tracing:
    enabled: true
    endpoint: "http://jaeger:4318/v1/traces"
    sample_rate: 1.0  # 1.0 = 100% sampling

Development

make dev        # hot reload with Air
make test       # all tests with race detector
make test-unit  # unit tests only
make coverage   # HTML coverage report
make lint       # golangci-lint
make fmt        # gofmt + goimports

Seeding test data

make seed
# or
bash scripts/seed.sh localhost:6379

Load Balancing Strategies

Strategy Description Best For
round_robin Cycles through backends equally Homogeneous backends
least_connections Always picks backend with fewest active connections Variable request durations
weighted_round_robin Smooth weighted distribution (Nginx algorithm) Heterogeneous backend capacity

Circuit Breaker States

CLOSED (normal) ──(failures > threshold)──► OPEN (reject all)
    ▲                                              │
    │                                        (timeout)
    │                                              ▼
    └────(success threshold met)──── HALF-OPEN (probe)

Configure globally under circuit_breaker: and enable per service with circuit_breaker.enabled: true.


Project Structure

.
├── cmd/gateway/main.go          ← Entry point
├── internal/
│   ├── auth/                    ← JWT + API key providers
│   ├── cache/                   ← Redis cache (interface + implementation)
│   ├── circuitbreaker/          ← gobreaker wrapper
│   ├── config/                  ← Typed config structs + Viper loader
│   ├── domain/                  ← Models + sentinel errors (no framework deps)
│   ├── handlers/                ← Health, admin HTTP handlers
│   ├── loadbalancer/            ← RR, LC, WRR strategies
│   ├── middleware/              ← Gin middleware (auth, cache, metrics, etc.)
│   ├── observability/           ← Prometheus metrics + OTEL tracing
│   ├── proxy/                   ← Reverse proxy + WebSocket proxy
│   ├── ratelimit/               ← Sliding window limiter
│   ├── registry/                ← Service registry
│   ├── router/                  ← Route wiring
│   └── server/                  ← http.Server wrapper
├── pkg/
│   ├── logger/                  ← Zap factory
│   └── redis/                   ← go-redis client factory
├── configs/config.yaml
├── deployments/
│   ├── Dockerfile
│   ├── docker-compose.yml
│   ├── prometheus/
│   └── grafana/
├── tests/
│   ├── unit/
│   └── integration/
├── scripts/seed.sh
├── Makefile
└── .air.toml

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors