16 KiB
API Workflows
End-to-end examples for common API gateway scenarios.
Setup
export BASE=http://localhost:3001
export COOKIE=/tmp/doorman.cookies
export DOORMAN_ADMIN_EMAIL="admin@example.com"
export DOORMAN_ADMIN_PASSWORD="YourStrongPassword123!"
# Login once
curl -sc "$COOKIE" -H 'Content-Type: application/json' \
-d "{\"email\":\"$DOORMAN_ADMIN_EMAIL\",\"password\":\"$DOORMAN_ADMIN_PASSWORD\"}" \
"$BASE/platform/authorization"
Workflow 1: REST API with API Key Injection
Goal: Publish /api/rest/customers/v1/* → http://httpbin.org with automatic API key injection.
1. Create Token Group
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/credit" -d '{
"api_credit_group": "demo-customers",
"api_key": "demo-secret-123",
"api_key_header": "x-api-key",
"credit_tiers": [
{
"tier_name": "default",
"credits": 999999,
"input_limit": 0,
"output_limit": 0,
"reset_frequency": "monthly"
}
]
}'
2. Create API
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/api" -d '{
"api_name": "customers",
"api_version": "v1",
"api_description": "Demo customers API",
"api_allowed_roles": ["admin"],
"api_allowed_groups": ["ALL"],
"api_servers": ["http://httpbin.org"],
"api_type": "REST",
"api_allowed_retry_count": 0,
"api_allowed_headers": ["content-type", "accept"],
"api_credits_enabled": true,
"api_credit_group": "demo-customers"
}'
3. Add Endpoints
# GET endpoint
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/endpoint" -d '{
"api_name": "customers",
"api_version": "v1",
"endpoint_method": "GET",
"endpoint_uri": "/get",
"endpoint_description": "Echo GET request"
}'
# POST endpoint
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/endpoint" -d '{
"api_name": "customers",
"api_version": "v1",
"endpoint_method": "POST",
"endpoint_uri": "/post",
"endpoint_description": "Echo POST request"
}'
4. Subscribe User
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/subscription/subscribe" -d '{
"username": "admin",
"api_name": "customers",
"api_version": "v1"
}'
5. Test
curl -sb "$COOKIE" "$BASE/api/rest/customers/v1/get?demo=1"
Workflow 2: Client-Specific Routing
Goal: Route clients to different upstream pools via client-key header.
1. Create Routing Entries
# Enterprise client routing
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/routing" -d '{
"routing_name": "customers-enterprise",
"routing_servers": ["http://premium-upstream-a:8080", "http://premium-upstream-b:8080"],
"routing_description": "Premium pool for enterprise clients",
"client_key": "enterprise-A"
}'
# Free tier client routing
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/routing" -d '{
"routing_name": "customers-free",
"routing_servers": ["http://shared-upstream:8080"],
"routing_description": "Shared pool for free tier",
"client_key": "free-tier"
}'
2. Test
# Enterprise tier
curl -sb "$COOKIE" -H 'client-key: enterprise-A' "$BASE/api/rest/customers/v1/get"
# Free tier
curl -sb "$COOKIE" -H 'client-key: free-tier' "$BASE/api/rest/customers/v1/get"
Workflow 3: Per-User Token Management
Goal: Track per-user credits and inject user-specific API keys.
1. Create Token Group
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/credit" -d '{
"api_credit_group": "openai-api",
"api_key": "default-openai-key",
"api_key_header": "Authorization",
"credit_tiers": [
{
"tier_name": "free",
"credits": 1000,
"input_limit": 100,
"output_limit": 100,
"reset_frequency": "monthly"
},
{
"tier_name": "premium",
"credits": 100000,
"input_limit": 10000,
"output_limit": 10000,
"reset_frequency": "monthly"
}
]
}'
Step 2: Assign User-Specific API Key
User-specific keys override the group default.
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/credit/alice" -d '{
"api_credit_group": "openai-api",
"api_key": "ALICE-PERSONAL-OPENAI-KEY",
"api_key_header": "Authorization",
"credit_tiers": [
{
"tier_name": "premium",
"credits": 100000,
"input_limit": 10000,
"output_limit": 10000,
"reset_frequency": "monthly"
}
]
}'
Step 3: Create API with Credits Enabled
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/api" -d '{
"api_name": "openai",
"api_version": "v1",
"api_description": "OpenAI API proxy",
"api_allowed_roles": ["user", "admin"],
"api_allowed_groups": ["ALL"],
"api_servers": ["https://api.openai.com"],
"api_type": "REST",
"api_credits_enabled": true,
"api_credit_group": "openai-api",
"api_allowed_headers": ["content-type", "authorization"]
}'
Step 4: Call Gateway
When Alice calls the gateway:
- Doorman injects her personal API key
- Deducts credits from her account
- Returns 401 with error code
GTW008when credits run out
# Alice's call (uses her personal key and credits)
curl -s -b "$COOKIE" -H 'Content-Type: application/json' \
-d '{"prompt": "Hello world"}' \
"$BASE/api/rest/openai/v1/completions"
Credit tracking:
- Input/output tokens counted against limits
- Credits reset based on
reset_frequency - View credit usage via
/platform/credit/{username}
Workflow 4: GraphQL Gateway
Scenario: Proxy a public GraphQL API with optional validation.
Gateway path: /api/graphql/{apiName}
Required header: X-API-Version: v1
Step 1: Create GraphQL API
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/api" -d '{
"api_name": "countries",
"api_version": "v1",
"api_description": "Public GraphQL API for country data",
"api_allowed_roles": ["admin", "user"],
"api_allowed_groups": ["ALL"],
"api_servers": ["https://countries.trevorblades.com"],
"api_type": "GraphQL",
"api_allowed_headers": ["content-type"],
"api_allowed_retry_count": 0
}'
Step 2: Subscribe User
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/subscription/subscribe" -d '{
"username": "admin",
"api_name": "countries",
"api_version": "v1"
}'
Step 3: Call GraphQL Gateway
curl -s -b "$COOKIE" \
-H 'Content-Type: application/json' \
-H 'X-API-Version: v1' \
-d '{"query":"{ country(code: \"US\") { name capital currency } }"}' \
"$BASE/api/graphql/countries"
Optional: Add GraphQL validation
Attach validation to verify operation shape and variables:
{
"api_validation_enabled": true,
"api_validation_schema": {
"query": {"required": true, "type": "string"},
"variables": {"required": false, "type": "object"}
}
}
Workflow 5: SOAP Gateway
Scenario: Proxy legacy SOAP APIs with XML validation.
Gateway path: /api/soap/{path}
Step 1: Create SOAP API
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/api" -d '{
"api_name": "legacy-orders",
"api_version": "v1",
"api_description": "Legacy SOAP order service",
"api_allowed_roles": ["admin"],
"api_allowed_groups": ["internal"],
"api_servers": ["http://legacy-soap.internal:8080"],
"api_type": "SOAP",
"api_allowed_retry_count": 1,
"api_allowed_headers": ["content-type", "soapaction"]
}'
Step 2: Add SOAP Endpoints
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/endpoint" -d '{
"api_name": "legacy-orders",
"api_version": "v1",
"endpoint_method": "POST",
"endpoint_uri": "/OrderService/CreateOrder",
"endpoint_description": "SOAP CreateOrder operation"
}'
Step 3: Add XML Validation (Optional)
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/endpoint/endpoint/validation" -d '{
"endpoint_id": "<endpoint_id>",
"validation_enabled": true,
"validation_schema": {
"validation_schema": {
"orderId": {"required": true, "type": "string"},
"customerId": {"required": true, "type": "string"}
}
}
}'
Step 4: Call SOAP Gateway
curl -s -b "$COOKIE" \
-H 'Content-Type: text/xml' \
-H 'SOAPAction: CreateOrder' \
-d '<soap:Envelope>...</soap:Envelope>' \
"$BASE/api/soap/legacy-orders/v1/OrderService/CreateOrder"
Monitoring and Health Checks
Health Endpoints
# Liveness probe (basic health)
curl -s "$BASE/platform/monitor/liveness"
# Returns: {"status": "alive"}
# Readiness probe (checks Redis/MongoDB)
curl -s "$BASE/platform/monitor/readiness"
# Returns: {"status": "ready", "mongodb": "connected", "redis": "connected"}
# Gateway status (public endpoint)
curl -s "$BASE/api/health"
# Returns: {"status": "ok", "uptime": 12345, "memory": {...}}
Metrics
# Requires authentication + manage_gateway permission
curl -s -b "$COOKIE" "$BASE/platform/monitor/metrics?range=24h"
Metrics include:
- Request counts per API
- Average response times
- Error rates
- Credit usage
- Rate limit hits
Logs
Via UI: Navigate to Logging section
Via API:
# View logs (requires view_logs permission)
curl -s -b "$COOKIE" "$BASE/platform/logging/logs?limit=100"
# Export logs (requires export_logs permission)
curl -s -b "$COOKIE" "$BASE/platform/logging/export?start_date=2024-01-01"
Log files:
backend-services/logs/doorman.log- Main application logbackend-services/logs/doorman-trail.log- Audit trail
Common Errors and Troubleshooting
GTW001: API Not Found
Error message: "API not found"
Causes:
- API with that name/version doesn't exist
- Typo in
api_nameorapi_version
Solutions:
# List all APIs
curl -s -b "$COOKIE" "$BASE/platform/api"
# Check API details
curl -s -b "$COOKIE" "$BASE/platform/api/customers/v1"
GTW002: No Endpoints Defined
Error message: "No endpoints defined for this API"
Causes:
- API created but no endpoints added
Solutions:
# Add at least one endpoint
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/endpoint" -d '{
"api_name": "customers",
"api_version": "v1",
"endpoint_method": "GET",
"endpoint_uri": "/health"
}'
GTW003: Endpoint Not Found
Error message: "Endpoint not found: GET /users"
Causes:
- Method/URI combination not added as an endpoint
- Typo in path or method
Solutions:
# List endpoints for API
curl -s -b "$COOKIE" "$BASE/platform/endpoint?api_name=customers&api_version=v1"
# Check URI matches exactly (including leading slash)
# Gateway path: /api/rest/customers/v1/users
# Endpoint URI should be: /users
GTW008: No Credits/Tokens
Error message: "No credits available"
Causes:
- User ran out of credits
- No token group assigned
- Credits not enabled for API
Solutions:
# Check user's credits
curl -s -b "$COOKIE" "$BASE/platform/credit/{username}"
# Add more credits
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/credit/{username}" -d '{
"api_credit_group": "demo-api",
"credit_tiers": [{"tier_name": "default", "credits": 100000, ...}]
}'
HTTP 403: Permission Denied
Error message: "You do not have permission..."
Causes:
- User lacks required role permission
- User not in allowed group for API
- User not subscribed to API
Solutions:
# Check user's roles
curl -s -b "$COOKIE" "$BASE/platform/user/{username}"
# Add required role
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/user/{username}/roles" -d '{
"roles": ["manage_apis"]
}'
# Subscribe to API
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/subscription/subscribe" -d '{
"username": "alice",
"api_name": "customers",
"api_version": "v1"
}'
CORS Errors
Error: "CORS policy: No 'Access-Control-Allow-Origin' header"
Causes:
- Client origin not in
ALLOWED_ORIGINS - Wildcard origin with credentials enabled
Solutions:
# Update environment variable
ALLOWED_ORIGINS=https://app.example.com,https://admin.example.com
CORS_STRICT=true
# Use CORS checker tool
curl -s -b "$COOKIE" -H 'Content-Type: application/json' -X POST \
"$BASE/platform/tools/cors/check" -d '{
"origin": "https://app.example.com",
"method": "GET",
"with_credentials": true
}'
CSRF Errors
Error: "Invalid CSRF token"
Causes:
X-CSRF-Tokenheader missing- CSRF token doesn't match cookie
- HTTPS not properly configured
Solutions:
# Ensure HTTPS is enabled
HTTPS_ONLY=true
# Include CSRF token in request
curl -s -b "$COOKIE" \
-H "X-CSRF-Token: $(grep csrf_token cookies.txt | awk '{print $7}')" \
-H 'Content-Type: application/json' \
-X POST "$BASE/platform/api" -d '{...}'
Request Too Large (413)
Error code: REQ001
Causes:
- Request body exceeds
MAX_BODY_SIZE_BYTES
Solutions:
# Increase limit for specific API type
MAX_BODY_SIZE_BYTES_SOAP=2097152 # 2MB for SOAP
MAX_BODY_SIZE_BYTES_REST=524288 # 512KB for REST
# Or increase global limit
MAX_BODY_SIZE_BYTES=2097152
Tips and Best Practices
API Configuration
- Restrict headers: Only allow headers that upstream needs via
api_allowed_headers - Use retries wisely: Set
api_allowed_retry_countbased on upstream idempotency - Enable validation: Validate requests at the gateway to protect upstream services
- Version APIs: Always use explicit versions (v1, v2, etc.)
Routing
- Client routing: Use
client-keyheader for blue/green deployments or premium tiers - Server pools: Provide multiple servers in
api_serversfor load balancing - Precedence: Remember routing > endpoint > API server selection
Security
- Subscribe users: Always require subscriptions to control access
- Use groups: Organize users into groups for easier access management
- Enable credits: Track and limit usage with credit system
- Validate inputs: Add endpoint validation to reject malformed requests early
Monitoring
- Enable JSON logs: Set
LOG_FORMAT=jsonin production - Ship to SIEM: Forward logs to centralized log management
- Monitor metrics: Regularly review
/platform/monitor/metrics - Set up alerts: Alert on error rates, credit exhaustion, rate limit hits
Performance
- Use Redis: Enable Redis for distributed rate limiting and caching
- Connection pooling: Upstream servers are pooled automatically
- Limit body sizes: Set appropriate
MAX_BODY_SIZE_BYTESper API type - Enable compression: Configure upstream responses with compression
Next Steps
- Configuration Reference - Complete environment variable guide
- Security Guide - Hardening and security best practices
- Operations Guide - Production deployment and runbooks
- Tools - CORS checker and diagnostics