# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview SecNex API Gateway is a Go-based API gateway built with chi/v5 routing. It acts as a reverse proxy with configurable features including path-based routing, prefix stripping, and structured logging. ## Build and Run ```bash cd app go run main.go ``` The gateway loads configuration from `gateway.yaml` (sibling to the `app/` directory). ## Architecture ### Directory Structure ``` app/ ├── main.go # Entry point ├── config/ # Configuration loading and types ├── server/ # Gateway, routes, hosts, targets, and API definitions ├── middlewares/ # HTTP middleware (logger, host) └── utils/ # Utility functions ``` ### Core Components **Gateway (`server/gateway.go`)** - Main server using chi/v5 router - Dynamically enables features via config: `request_id`, `real_ip`, `logger`, `host` - Configures proxy directors for each API - Registers route handlers and starts HTTP server **Routes (`server/routes.go`)** - Creates handlers for each route configured in `gateway.yaml` - For each route: 1. Finds the matching API backend target 2. Creates a handler with optional strip prefix middleware 3. Registers with chi router using `r.Handle()` (method-agnostic) **API (`server/api.go`)** - Links hosts to backend targets - Implements `http.Handler` interface - Delegates to the reverse proxy **Hosts (`server/host.go`)** - Host definitions for virtual hosting - Domain-based routing support **Targets (`server/target.go`)** - Backend service definitions - Creates `httputil.NewSingleHostReverseProxy` instances ### Configuration Flow 1. `config.NewFile("../gateway.yaml")` loads YAML 2. `server.NewGateway(cfg)` creates gateway with chi router 3. `server.NewRoutes(cfg, apis)` creates route handlers 4. `routes.Register(g.router)` registers handlers 5. Gateway starts HTTP server ### Middleware Chain **Global Middleware** (applied via chi middleware): 1. RequestID - adds unique request ID 2. RealIP - determines real client IP 3. Logger - structured JSON logging 4. Host - logs host header **Per-Route Middleware** (applied in order): 1. StripPrefix - removes prefix from path before proxying (if enabled) ### Key Implementation Details **Strip Prefix Middleware** (`server/routes.go`) - Removes specified prefix from request path before proxying - Ensures resulting path starts with `/` **Route Handler Pattern** Each route in `gateway.yaml` must have: - `id` - unique route identifier - `api` - API ID to use (references an API entry) - `path` - chi route pattern (e.g., `/api/v1/*`) - `strip_prefix` - optional prefix removal ### Module Structure The codebase uses an internal Go module: ``` git.secnex.io/secnex/api-gateway ``` Internal imports use this path (e.g., `git.secnex.io/secnex/api-gateway/config`). ### Logging Uses `git.secnex.io/secnex/masterlog` with: - JSON encoder - Pseudonymizer for sensitive fields (`user_id`, `email`, `ip`) - Debug-level logging enabled in main.go - Custom `LoggerMiddleware` for structured HTTP request logging ### Dependencies - `github.com/go-chi/chi/v5` - HTTP router - `git.secnex.io/secnex/masterlog` - Structured logging - `go.yaml.in/yaml/v3` - YAML configuration parsing - `gorm.io/gorm` - Database ORM (for future use) - `gorm.io/driver/postgres` - PostgreSQL driver (for future use) ## Configuration Reference ```yaml gateway: host: "0.0.0.0" port: 8080 features: - request_id - real_ip - logger - host hosts: - id: "host-001" name: "localhost" domain: "localhost:8080" targets: - id: "target-001" name: "httpbin" url: "https://httpbin.org" apis: - id: "api-001" host: "host-001" target: "target-001" routes: - id: "route-001" api: "api-001" path: "/api/v1/*" strip_prefix: enabled: true prefix: "/api/v1" ```