Files
api-gateway/.docs/usage.md
2026-02-06 00:08:27 +01:00

427 lines
8.1 KiB
Markdown

# Usage
## Running the Gateway
### Local Development
```bash
cd app
go run main.go
```
The gateway will start on the configured host and port (default: `0.0.0.0:8080`).
### Docker
```bash
# Pull and run (builds locally if image not available)
docker compose up -d
# View logs
docker compose logs -f gateway
# Stop
docker compose down
```
### Build from Source
```bash
cd app
go build -o gateway main.go
./gateway
```
## Health Check
Check if the gateway is running:
```bash
curl http://localhost:8080/_/health
```
Response: `OK`
## Making Requests
After configuring routes in `gateway.yaml`, make requests to the gateway:
```bash
# Example: Request to a route configured at /api/v1/*
curl http://localhost:8080/api/v1/users
# All HTTP methods are supported
curl -X POST http://localhost:8080/api/v1/data
curl -X PUT http://localhost:8080/api/v1/data/123
curl -X DELETE http://localhost:8080/api/v1/data/123
```
## Authentication
### Using API Key Authentication
**Configuration:**
```yaml
security:
auth:
enabled: true
header: "X-Api-Key"
```
**Valid request:**
```bash
curl -H "X-Api-Key: your-secret-key" http://localhost:8080/api/v1/data
```
**Invalid request (missing header):**
```bash
curl http://localhost:8080/api/v1/data
# Returns: 401 Unauthorized
```
### Using Bearer Token Authentication
**Configuration:**
```yaml
security:
auth:
enabled: true
header: "Authorization"
```
**Valid request:**
```bash
curl -H "Authorization: Bearer your-token-here" http://localhost:8080/api/v1/data
```
### Path-Based Authentication Examples
#### All Paths Require Auth
**Configuration:**
```yaml
security:
auth:
enabled: true
header: "X-Api-Key"
path:
include: []
exclude: []
```
All requests to this route require authentication.
#### Only Specific Paths Require Auth (Include)
**Configuration:**
```yaml
security:
auth:
enabled: true
header: "X-Api-Key"
path:
include: ["/api/admin/*", "/api/users/*/profile"]
exclude: []
```
**Request examples:**
```bash
# Requires auth (matches include)
curl -H "X-Api-Key: key" http://localhost:8080/api/admin/users
curl -H "X-Api-Key: key" http://localhost:8080/api/users/123/profile
# No auth required (doesn't match include)
curl http://localhost:8080/api/public/data
curl http://localhost:8080/api/health
```
#### All Paths Except Specific Ones Require Auth (Exclude)
**Configuration:**
```yaml
security:
auth:
enabled: true
header: "X-Api-Key"
path:
include: []
exclude: ["/api/health", "/api/public/*"]
```
**Request examples:**
```bash
# No auth required (matches exclude)
curl http://localhost:8080/api/health
curl http://localhost:8080/api/public/data
# Requires auth (doesn't match exclude)
curl -H "X-Api-Key: key" http://localhost:8080/api/users
curl -H "X-Api-Key: key" http://localhost:8080/api/admin/settings
```
## Route Examples
### Strip Prefix Example
**Configuration:**
```yaml
routes:
- id: "api"
api: "api-001"
path: "/api/v1/*"
strip_prefix:
enabled: true
prefix: "/api/v1"
```
**Request flow:**
- Client requests: `/api/v1/users/123`
- Gateway strips: `/api/v1`
- Backend receives: `/users/123`
### Multiple Routes Example
**Configuration:**
```yaml
routes:
- id: "public-route"
api: "api-001"
path: "/public/*"
strip_prefix:
enabled: true
prefix: "/public"
security:
auth:
enabled: false
- id: "api-route"
api: "api-001"
path: "/api/v1/*"
strip_prefix:
enabled: true
prefix: "/api/v1"
security:
auth:
enabled: true
header: "X-Api-Key"
```
**Requests:**
```bash
# Public route - no auth, backend receives /status
curl http://localhost:8080/public/status
# API route - requires auth, backend receives /users
curl -H "X-Api-Key: key" http://localhost:8080/api/v1/users
```
## Logging
The gateway uses structured JSON logging via `masterlog`. All HTTP requests are logged with:
- Request ID (if enabled)
- Client IP (if real_ip enabled)
- Request method and path
- Response status code
- Request duration
- Host header
**Example log output:**
```json
{
"level": "info",
"msg": "HTTP Request",
"method": "GET",
"path": "/api/v1/users",
"status": 200,
"duration": "45ms",
"host": "localhost:8080",
"ip": "127.0.0.1:52342"
}
```
### Debug Logging
To enable detailed authentication logging, set DEBUG level in `main.go`:
```go
masterlog.SetLevel(masterlog.LevelDebug)
```
This will output detailed auth decision logs:
```json
{
"level": "debug",
"msg": "AuthMiddleware: Checking if path requires auth",
"path": "/api/v1/users",
"requires_auth": true,
"include": [],
"exclude": ["/api/v1/public/*"]
}
```
## Troubleshooting
### Gateway fails to start
1. Check if port is already in use:
```bash
lsof -i :8080
```
2. Verify configuration file exists and is valid YAML:
```bash
cat ../gateway.yaml
```
3. Check logs for detailed error messages
### 401 Unauthorized
- Verify auth header is included
- Check header name matches configuration (case-sensitive)
- Verify path is not excluded from auth (check exclude patterns)
- Enable DEBUG logging to see auth decision process
### 404 Not Found
- Verify the route path matches your request
- Check chi route pattern syntax (use `/*` for wildcards)
- Ensure the route is registered (check startup logs)
### Backend connection errors
- Verify target URL is correct in configuration
- Check backend service is running and accessible
- Verify network connectivity from gateway to backend
- Check DNS resolution if using domain names
### Route not matching
- Ensure request path matches the route pattern exactly
- Remember that `/*` matches zero or more path segments
- Check that multiple routes don't have conflicting patterns
### Auth not working as expected
1. Enable DEBUG logging to see auth decisions:
```go
masterlog.SetLevel(masterlog.LevelDebug)
```
2. Check the logs for:
- Whether the path requires auth
- Whether the auth header is present
- Which patterns are being matched
3. Verify your include/exclude patterns:
- Wildcards end with `*`
- Patterns are prefix-based (e.g., `/api/v1/public/test/*`)
## Performance Considerations
- The gateway uses Go's `httputil.ReverseProxy` for efficient proxying
- HTTP/2 is supported when both client and backend support it
- Keep-alive connections are reused by default
- Consider connection pooling for high-traffic scenarios
- Monitor memory usage with high request volumes
## Common Patterns
### API Versioning with Auth
```yaml
routes:
- id: "v1-public-api"
api: "api-001"
path: "/api/v1/public/*"
strip_prefix:
enabled: true
prefix: "/api/v1/public"
security:
auth:
enabled: false
- id: "v1-protected-api"
api: "api-001"
path: "/api/v1/*"
strip_prefix:
enabled: true
prefix: "/api/v1"
security:
auth:
enabled: true
header: "X-Api-Key"
```
### Mixed Authentication
```yaml
routes:
- id: "user-api"
api: "api-001"
path: "/users/*"
security:
auth:
enabled: true
header: "X-Api-Key"
path:
include: []
exclude: ["/users/login", "/users/register"]
- id: "admin-api"
api: "api-001"
path: "/admin/*"
security:
auth:
enabled: true
header: "Authorization"
path:
include: []
exclude: []
```
### Microservices Routing
```yaml
targets:
- id: "user-service"
name: "User Service"
url: "https://user-service.internal"
- id: "order-service"
name: "Order Service"
url: "https://order-service.internal"
apis:
- id: "user-api"
host: "host-001"
target: "user-service"
- id: "order-api"
host: "host-001"
target: "order-service"
routes:
- id: "users-route"
api: "user-api"
path: "/users/*"
strip_prefix:
enabled: true
prefix: "/users"
security:
auth:
enabled: true
header: "X-Api-Key"
- id: "orders-route"
api: "order-api"
path: "/orders/*"
strip_prefix:
enabled: true
prefix: "/orders"
security:
auth:
enabled: true
header: "Authorization"
```