RustMock 0.3.3

Lightning-fast, lightweight API mock server with OpenAPI support and beautiful React dashboard
Documentation
# Smart Proxy Mode - Usage Guide

## Overview

Smart Proxy Mode enables **hybrid mock + real API testing**. You can:
- Keep most endpoints mocked while proxying specific ones to production
- Test new endpoints in isolation while using real data for the rest
- Simulate errors on specific endpoints without affecting others
- Mix and match mock and proxy behaviors for ultimate flexibility

## Quick Start

### 1. Global Default Proxy

Set a default proxy URL that catches all unmocked requests:

```bash
# Via environment variable
export DEFAULT_PROXY_URL="https://api.production.com"
./rust-mock

# Via CLI argument
./rust-mock --default-proxy-url https://api.production.com
```

### 2. Per-Endpoint Proxy

Add an endpoint with a `proxy_url` field:

```bash
curl -X POST http://localhost:8090/__mock/endpoints \
  -H "Content-Type: application/json" \
  -d '{
    "method": "GET",
    "path": "/api/users",
    "proxy_url": "https://api.production.com",
    "response": {},
    "status": 200
  }'
```

### 3. Runtime Proxy Configuration

Manage the global proxy at runtime:

```bash
# Set default proxy
curl -X POST http://localhost:8090/__mock/proxy \
  -H "Content-Type: application/json" \
  -d '{"url": "https://api.production.com"}'

# Get current proxy config
curl http://localhost:8090/__mock/proxy

# Delete default proxy
curl -X DELETE http://localhost:8090/__mock/proxy
```

## How It Works

### Request Flow

```
Incoming Request
Check dynamic endpoints
┌─────────────────────┐
│ Endpoint found?     │
└──────┬──────────────┘
    ┌──┴──┐
   YES   NO
    │     │
    ↓     ↓
Has      Default
proxy?   proxy?
    │     │
  ┌─┴─┐ ┌─┴─┐
 YES NO YES NO
  │   │   │   │
  ↓   ↓   ↓   ↓
Proxy Mock Proxy 404
```

### Priority Order

1. **Endpoint with `proxy_url`** → Forward to specified URL
2. **Endpoint with `response`** → Return mock response
3. **Global `default_proxy_url`** → Forward to default URL
4. **No match** → 404 Not Found

## Use Cases

### Case 1: Test New Endpoint with Production Data

```bash
# Set global proxy to production
export DEFAULT_PROXY_URL="https://api.prod.com"

# Add ONLY the new endpoint as a mock
curl -X POST http://localhost:8090/__mock/endpoints \
  -d '{
    "method": "POST",
    "path": "/api/v2/new-feature",
    "response": {"status": "success", "data": {"id": 123}},
    "status": 201
  }'

# Result:
# - POST /api/v2/new-feature → MOCK (201)
# - GET /api/users → PROXY to prod
# - GET /api/orders → PROXY to prod
# - Everything else → PROXY to prod
```

### Case 2: Simulate Errors on Specific Endpoints

```bash
# Set global proxy
curl -X POST http://localhost:8090/__mock/proxy \
  -d '{"url": "https://api.prod.com"}'

# Mock a payment failure
curl -X POST http://localhost:8090/__mock/endpoints \
  -d '{
    "method": "POST",
    "path": "/api/payment",
    "response": {"error": "Payment gateway timeout"},
    "status": 503
  }'

# Result:
# - POST /api/payment → MOCK (503 error)
# - All other endpoints → PROXY to prod
```

### Case 3: Multi-Environment Proxying

```bash
# Auth goes to staging
curl -X POST http://localhost:8090/__mock/endpoints \
  -d '{
    "method": "POST",
    "path": "/api/auth/login",
    "proxy_url": "https://auth.staging.com",
    "response": {},
    "status": 200
  }'

# Payments go to production
curl -X POST http://localhost:8090/__mock/endpoints \
  -d '{
    "method": "POST",
    "path": "/api/payments",
    "proxy_url": "https://payments.prod.com",
    "response": {},
    "status": 200
  }'

# Result:
# - POST /api/auth/login → PROXY to staging
# - POST /api/payments → PROXY to production
# - Different services, different environments!
```

### Case 4: Test Edge Cases Without Touching Production

```bash
# Most requests go to prod
export DEFAULT_PROXY_URL="https://api.prod.com"

# But test rate limiting locally
curl -X POST http://localhost:8090/__mock/endpoints \
  -d '{
    "method": "GET",
    "path": "/api/users",
    "response": {"error": "Rate limit exceeded"},
    "status": 429,
    "headers": {
      "Retry-After": "60",
      "X-RateLimit-Remaining": "0"
    }
  }'
```

## Features

### ✅ Header Forwarding

All request headers (except `host`, `connection`, `transfer-encoding`) are forwarded to the upstream server.

### ✅ Query Parameter Forwarding

Query parameters are preserved and forwarded to the upstream:

```bash
GET /api/users?page=2&limit=10
# Proxied to: https://api.prod.com/api/users?page=2&limit=10
```

### ✅ Body Forwarding

Request bodies are forwarded as-is:

```bash
POST /api/users
Body: {"name": "John", "email": "john@example.com"}
# Proxied with the same body
```

### ✅ Response Passthrough

Proxy responses are returned unchanged:
- Status codes preserved
- Response headers forwarded
- Response body forwarded

### ✅ Request Logging

All proxied requests are logged with:
- Original request data
- Response data
- `proxied_to` field showing the target URL

Example log entry:

```json
{
  "method": "GET",
  "path": "/api/users",
  "status": 200,
  "response_body": {"users": [...]},
  "proxied_to": "https://api.prod.com/api/users",
  "timestamp": "2025-01-14T12:34:56Z"
}
```

### ✅ Error Handling

If a proxy request fails:
- Returns `502 Bad Gateway`
- Includes error details in response body
- Logs the failure

```json
{
  "error": "Proxy request failed",
  "details": "Connection timeout"
}
```

## Configuration

### Environment Variables

- `DEFAULT_PROXY_URL` - Default proxy URL for unmocked endpoints

### CLI Arguments

```bash
./rust-mock --help
# Shows:
#   --default-proxy-url <URL>    Default proxy URL for unmocked endpoints
```

### Endpoint Configuration

```json
{
  "method": "GET",
  "path": "/api/users",
  "response": {"users": []},      // Used if proxy_url is not set
  "status": 200,                  // Used if proxy_url is not set
  "headers": {...},               // Custom headers (for mock mode)
  "proxy_url": "https://api.prod.com"  // Optional: proxy to this URL
}
```

## Testing

Run the proxy mode tests:

```bash
cargo test --test integration_tests -- proxy
```

Tests include:
- Proxy configuration endpoints
- Per-endpoint proxying
- Default proxy fallback
- Mixed mock + proxy mode
- Query parameter forwarding
- POST body forwarding
- Proxy failure handling

## UI Integration

The web UI includes:
- **Proxy tab** in endpoint form for setting `proxy_url`
- **Proxy configuration panel** for global proxy settings
- **Proxy indicator** in logs showing where requests were proxied

## Performance

- Timeout: 30 seconds per proxy request
- Connection pooling: Handled by `reqwest`
- Concurrent requests: Supported
- No caching: All requests forwarded in real-time

## Security

⚠️ **Important Security Notes:**

- Proxy mode forwards ALL headers and data to upstream
- Ensure upstream URLs are trusted
- Use HTTPS for upstream URLs in production
- Sensitive headers like `Authorization` are forwarded

## Troubleshooting

### Proxy returns 502

Check:
1. Is the upstream URL accessible?
2. Does it return valid HTTP responses?
3. Check logs for detailed error message

### Proxy ignores custom headers

Custom `headers` field only applies to mock mode. In proxy mode, upstream response headers are used.

### Query params not forwarded

Check URL encoding. Query params are forwarded automatically.

## Examples

See `tests/integration_tests.rs` for comprehensive examples.

## API Reference

### GET `/__mock/proxy`

Get current default proxy configuration.

**Response:**
```json
{
  "proxy_url": "https://api.prod.com",
  "enabled": true
}
```

### POST `/__mock/proxy`

Set default proxy URL.

**Request:**
```json
{
  "url": "https://api.prod.com"
}
```

**Response:**
```json
{
  "proxy_url": "https://api.prod.com",
  "enabled": true
}
```

### DELETE `/__mock/proxy`

Remove default proxy.

**Response:**
```json
{
  "deleted": true
}
```

---

Happy proxying! 🚀