Files
api-gateway/CLAUDE.md
2026-02-05 23:59:17 +01:00

151 lines
3.9 KiB
Markdown

# 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"
```