Skip to content

Mock API Architecture ​

Phony's Mock API system generates dynamic REST APIs from PGDL schemas, enabling frontend development and integration testing without backend dependencies.

Implementation status

Target design — the hosted Mock API service is not built yet. The local phony mock start server is planned as part of the CLI.

Why This Is the Hosted Piece ​

In Phony's local-first architecture, database sync and snapshots run in the customer's infrastructure because they touch production row data. The Mock API is the one genuinely hosted product surface — and it can be, precisely because it serves synthetic data only: responses are generated on the fly from PGDL schemas (or from anonymized snapshots a customer has explicitly exported for mocking). No customer row data is ever involved, so hosting it on Phony's edge carries none of the trust or compliance weight that made sync local-first.

The free/offline alternative is the local mock server:

bash
phony mock start --schema api.pgdl.json --port 3000

Same Rust engine, same schemas, no cloud account — hosted endpoints add a stable public URL, TLS, caching, custom domains, and team-shared configuration. Mock endpoints never serve synced production data; they serve PGDL-generated synthetic records.

Architecture Overview ​

┌─────────────────────────────────────────────────────────────────────────┐
│                    MOCK API ARCHITECTURE                                 │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  CLIENT REQUEST                                                         │
│  ══════════════                                                         │
│  GET https://mock.phony.cloud/ep_abc123/api/users?page=1                │
│                      │                                                   │
│                      ▼                                                   │
│  ┌─────────────────────────────────────────────────────────────────────┐│
│  │                         EDGE (Cloudflare)                           ││
│  │  • TLS Termination                                                  ││
│  │  • DDoS Protection                                                  ││
│  │  • Response Caching (when enabled)                                  ││
│  │  • Geographic routing                                               ││
│  └───────────────────────────────┬─────────────────────────────────────┘│
│                                  │                                      │
│                                  ▼                                      │
│  ┌─────────────────────────────────────────────────────────────────────┐│
│  │                      MOCK API SERVER (Go)                           ││
│  │                                                                      ││
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐                 ││
│  │  │   Router    │  │   Schema    │  │  Response   │                 ││
│  │  │             │─►│   Loader    │─►│  Generator  │                 ││
│  │  │ /ep_{id}/*  │  │             │  │             │                 ││
│  │  └─────────────┘  └─────────────┘  └──────┬──────┘                 ││
│  │                                           │                         ││
│  │                                           ▼                         ││
│  │                                   ┌─────────────┐                   ││
│  │                                   │  Rust Core  │                   ││
│  │                                   │  (N-gram)   │                   ││
│  │                                   │  5M rec/s   │                   ││
│  │                                   └─────────────┘                   ││
│  │                                                                      ││
│  └─────────────────────────────────────────────────────────────────────┘│
│                                  │                                      │
│                                  ▼                                      │
│  RESPONSE                                                               │
│  ════════                                                               │
│  {                                                                      │
│    "data": [                                                           │
│      { "id": "usr_abc", "name": "Mehmet", "email": "m@ex.com" },       │
│      { "id": "usr_def", "name": "Ayşe", "email": "a@ex.com" }          │
│    ],                                                                   │
│    "meta": { "page": 1, "total": 100 }                                 │
│  }                                                                      │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Endpoint Configuration ​

Schema-Driven Endpoints ​

Each endpoint is defined by a PGDL schema:

json
{
  "endpoint": {
    "path": "/api/users",
    "method": "GET",
    "description": "List users with pagination"
  },

  "schema": {
    "generators": {
      "id": {
        "type": "logic",
        "algorithm": "uuid_v7"
      },
      "name": {
        "type": "model",
        "source": "tr_TR/full_names",
        "generation": { "mode": "word" }
      },
      "email": {
        "type": "template",
        "pattern": "{{lowercase(name)}}@example.com",
        "unique": true
      },
      "created_at": {
        "type": "logic",
        "algorithm": "datetime_between",
        "params": { "start": "-1year", "end": "now" }
      }
    },
    "output": ["id", "name", "email", "created_at"]
  },

  "response": {
    "wrapper": {
      "data": "{{records}}",
      "meta": {
        "page": "{{query.page | default: 1}}",
        "per_page": "{{query.per_page | default: 20}}",
        "total": "{{total}}"
      }
    },
    "count": "{{query.per_page | default: 20}}",
    "seed": "{{query.seed | default: null}}"
  }
}

Dynamic Path Parameters ​

json
{
  "endpoint": {
    "path": "/api/users/:id",
    "method": "GET"
  },
  "response": {
    "count": 1,
    "seed": "{{params.id}}"
  }
}

When accessing /api/users/123, the seed 123 ensures deterministic output - same ID always returns same user.


Request Handling ​

Query Parameters ​

ParameterDescriptionExample
pagePage number?page=2
per_pageItems per page (max 100)?per_page=50
seedRandom seed for determinism?seed=12345
localeOverride locale?locale=en_US
formatResponse format?format=csv

Request Body (POST/PUT) ​

For mutation endpoints, request body can influence response:

json
// POST /api/users
// Request:
{
  "name": "Custom Name"
}

// Response includes submitted data + generated fields:
{
  "id": "usr_generated",
  "name": "Custom Name",
  "email": "custom.name@example.com",
  "created_at": "2026-01-31T10:00:00Z"
}

Response Modes ​

List Mode ​

GET /api/users
→ Returns array of generated records

Single Mode ​

GET /api/users/:id
→ Returns single record (deterministic by ID)

Streaming Mode (Large datasets) ​

GET /api/users?format=ndjson&count=10000
→ Returns newline-delimited JSON stream

Error Simulation ​

json
{
  "simulation": {
    "error_rate": 0.05,
    "errors": [
      { "status": 500, "body": { "error": "Internal server error" }, "weight": 70 },
      { "status": 503, "body": { "error": "Service unavailable" }, "weight": 30 }
    ],
    "latency": {
      "min_ms": 50,
      "max_ms": 200,
      "p99_ms": 500
    }
  }
}

Routing Architecture ​

URL Structure ​

https://mock.phony.cloud/{endpoint_id}/{path}

Examples:
https://mock.phony.cloud/ep_abc123/api/users
https://mock.phony.cloud/ep_abc123/api/users/456
https://mock.phony.cloud/ep_abc123/api/orders

Custom Domains (Business tier) ​

https://api-staging.yourcompany.com/users
  └── CNAME → mock.phony.cloud
  └── Routes to ep_abc123

Multi-Endpoint Projects ​

A project can have multiple endpoints sharing the same base URL:

Project: "E-Commerce API"
├── GET  /api/users           → ep_001
├── GET  /api/users/:id       → ep_002
├── POST /api/users           → ep_003
├── GET  /api/products        → ep_004
├── GET  /api/orders          → ep_005
└── GET  /api/orders/:id/items → ep_006

Caching Strategy ​

┌─────────────────────────────────────────────────────────────────────────┐
│                    CACHING LAYERS                                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  LAYER 1: Edge Cache (Cloudflare)                                       │
│  ═══════════════════════════════                                        │
│  • Cache-Control: public, max-age=60 (when seed provided)              │
│  • Cache key: URL + seed parameter                                      │
│  • Bypass: No seed = no edge cache                                      │
│                                                                          │
│  LAYER 2: Response Cache (Redis)                                        │
│  ═══════════════════════════════                                        │
│  • Schema hash + seed → cached response                                 │
│  • TTL: 5 minutes                                                       │
│  • Invalidated on schema update                                         │
│                                                                          │
│  LAYER 3: Schema Cache (Memory)                                         │
│  ══════════════════════════════                                         │
│  • Loaded PGDL schemas cached in memory                                  │
│  • Refreshed on update webhook                                          │
│                                                                          │
│  CACHE BEHAVIOR:                                                        │
│  ════════════════                                                       │
│  ?seed=123    → Fully cacheable (same output every time)               │
│  (no seed)    → Fresh generation on each request                       │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

CORS Configuration ​

json
{
  "cors": {
    "enabled": true,
    "origins": ["*"],
    "methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    "headers": ["Content-Type", "Authorization", "X-Request-ID"],
    "credentials": false,
    "max_age": 86400
  }
}

For production, restrict origins:

json
{
  "cors": {
    "origins": [
      "https://app.yourcompany.com",
      "http://localhost:3000"
    ]
  }
}

Authentication Simulation ​

API Key ​

json
{
  "auth": {
    "type": "api_key",
    "header": "X-API-Key",
    "valid_keys": ["test_key_123", "dev_key_456"],
    "error_response": {
      "status": 401,
      "body": { "error": "Invalid API key" }
    }
  }
}

Bearer Token ​

json
{
  "auth": {
    "type": "bearer",
    "tokens": ["token_abc", "token_def"],
    "jwt_validation": {
      "enabled": true,
      "issuer": "https://auth.yourcompany.com",
      "audience": "api"
    }
  }
}

Webhook Integration ​

On-Request Webhooks ​

Forward requests to your system for logging/debugging:

json
{
  "webhooks": {
    "on_request": {
      "url": "https://yourapp.com/webhook/mock-request",
      "include": ["headers", "query", "body"],
      "async": true
    }
  }
}

Request Logging ​

All requests are logged and available in dashboard:

json
{
  "request_id": "req_abc123",
  "endpoint_id": "ep_def456",
  "method": "GET",
  "path": "/api/users",
  "query": { "page": "1" },
  "response_time_ms": 45,
  "status": 200,
  "timestamp": "2026-01-31T10:00:00Z"
}

Performance ​

MetricValue
Cold start< 50ms
Warm response< 20ms
Throughput10,000 req/sec per endpoint
Max response size10MB
Max records per request10,000

Rate Limits ​

TierRequests/minBandwidth/day
Free100100 MB
Starter1,0001 GB
Team10,00010 GB
Business100,000100 GB

Local Development ​

Run mock API locally using the CLI:

bash
# Start local mock server
phony mock start --schema api.pgdl.json --port 3000

# Output:
# Mock API running at http://localhost:3000
# Endpoints:
#   GET  /api/users
#   GET  /api/users/:id
#   POST /api/users

Local mode uses the same Rust core as cloud, ensuring identical behavior.

Phony Cloud — Documentation & Specification