Platform OAS Generation Tools
Tools for generating platform-enhanced OpenAPI specifications from producer OAS.
Overview
The platform OAS generator transforms producer-defined API specifications into platform-enhanced versions by:
- Preserving fragment references - Keeps
$refto centrally-versioned fragments (NOT inlined) - Injecting sparse fieldsets - Adds
fields[:resource]=field1,field2parameter to GET operations - Adding platform metadata - Documents platform features and capabilities
Architecture
Producer OAS (domain/producer/)
↓
Uses $ref to common fragments (domain/fragments/)
↓
Platform OAS Generator (this tool)
↓
1. Preserve $ref to fragments (centrally versioned)
2. Inject sparse fieldsets
3. Add platform metadata
↓
Platform OAS (domain/platform/)
↓
Used for API portal documentation and Prism mock servers
(Still references fragments via $ref)
Usage
Basic Usage
cd domain/tools
python generate_platform_oas.py ../producer/vpd-submission-returns-api.yamlOutput: domain/platform/vpd-submission-returns-api.yaml
With Virtual Environment
# Create venv
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install pyyaml
# Run generator
python generate_platform_oas.py ../producer/vpd-submission-returns-api.yamlWhat the Generator Does
1. Preserves Fragment References
Producer OAS:
responses:
'400':
$ref: '../fragments/responses/v1/oas.yaml#/BadRequest'Platform OAS (generated):
responses:
'400':
$ref: '../fragments/responses/v1/oas.yaml#/BadRequest' # Preserved - fragments are centrally versionedWhy preserve $ref?
- Fragments are centrally versioned and controlled (e.g.,
headers/v1/,headers/v2/) - Changes to fragments propagate to all APIs using that version
- Avoids duplication and version drift
- APIs can migrate to new fragment versions independently
- API portal can resolve refs at runtime
2. Injects Sparse Fieldsets
For every GET operation, adds a fields parameter:
parameters:
- name: fields
in: query
description: |
Platform-provided sparse fieldsets. Request specific fields from the response.
Format: fields[:submission]=field1,field2,field3
Available fields: acknowledgementReference, vpdApprovalNumber, periodKey, ...
schema:
type: string
pattern: '^fields\[:submission\]=([\w]+,?)+$'
examples:
singleField:
value: "fields[:submission]=acknowledgementReference"
multipleFields:
value: "fields[:submission]=acknowledgementReference,totalDutyDue,vat"The generator:
- Extracts field names from the response schema
- Lists all available fields in the description
- Provides realistic examples
3. Adds Platform Metadata
info:
x-platform-generated: true
x-platform-features:
sparseFieldsets: true
rateLimiting: true
correlationId: true
etags: trueDirectory Structure
domain/
├── fragments/ # Centrally-versioned fragments
│ ├── headers/v1/oas.yaml # Common headers (v1)
│ ├── schemas/v1/oas.yaml # Common schemas (v1)
│ ├── responses/v1/oas.yaml # Common responses (v1)
│ └── parameters/v1/oas.yaml # Common parameters (v1)
├── producer/
│ └── vpd-submission-returns-api.yaml # Source (maintained by producers)
├── platform/
│ └── vpd-submission-returns-api.yaml # Generated (published to API portal)
└── tools/
├── generate_platform_oas.py # Generator script
└── README.md # This file
Requirements
- Python 3.7+
- PyYAML (
pip install pyyaml)
Producer Workflow
-
Create/update producer OAS in
domain/producer/- Use
$refto platform common fragments - Focus on domain logic only
- No need to mention sparse fieldsets
- Use
-
Generate platform OAS
cd domain/tools python generate_platform_oas.py ../producer/vpd-submission-returns-api.yaml -
Validate platform OAS
cd ../platform/generated redocly lint vpd-submission-returns-api.yaml -
Publish platform OAS to API portal
- Platform OAS is the consumer-facing specification
- Shows all platform features and available fields
Benefits
For Producers
- Write clean, domain-focused OAS
- Platform features added automatically
- No duplication of common elements
For Consumers
- Complete documentation including platform features
- All available fields enumerated
- Realistic examples for sparse fieldsets
For Platform
- Single source of truth for common elements
- Consistent feature injection across all APIs
- Easy to add new platform features
Troubleshooting
FileNotFoundError: Referenced file not found
Check that relative paths in $ref are correct:
# ✅ Correct (relative to producer OAS location)
$ref: '../fragments/headers.yaml#/X-Correlation-Id-Response'
# ❌ Wrong
$ref: './fragments/headers.yaml#/X-Correlation-Id-Response'Missing fields in sparse fieldsets
Generator extracts fields from the response schema. Ensure:
- GET operation has a 200 response
- Response has
application/jsoncontent type - Content has a
schemawithproperties
Invalid YAML in generated output
Check that all $ref targets are valid YAML and resolve correctly.
Mock Server Tools
Tools for running Prism mock servers with realistic network latency simulation for testing.
Starting a Mock Server
cd domain/tools
./prism-mock-server.sh ../platform/vpd-submission-returns-api.yaml 4010Default configuration:
- Port: 4010 (or specify as second argument)
- Delays: 0-500ms random per request
- Distribution: Uniform random
Making Mock Requests with Delays
The mock client wrapper automatically injects random delays:
# GET request with random delay
./mock-client.sh http://localhost:4010/duty/vpd/submission-returns/v1?acknowledgementReference=ACK-2026-01-27-000123
# POST request with random delay
./mock-client.sh http://localhost:4010/duty/vpd/submission-returns/v1 \
-X POST \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: test-123" \
-d @examples/submission-request.jsonThe client generates a random delay (0-500ms by default) and injects it as Prefer: wait=<ms> header to Prism.
Manual Delay Control
Use curl directly with specific delays:
# Fixed 250ms delay
curl -H "Prefer: wait=250" http://localhost:4010/duty/vpd/submission-returns/v1?acknowledgementReference=ACK-123
# No delay
curl http://localhost:4010/duty/vpd/submission-returns/v1?acknowledgementReference=ACK-123Configuring Delays
Edit the mock-client.sh script to change delay ranges:
MIN_DELAY=100 # Change from 0
MAX_DELAY=2000 # Change from 500Requirements
- Prism CLI:
npm install -g @stoplight/prism-cli