OpenAPI Support
Testfly parses your OpenAPI spec to build a real relational database. Here's exactly what we support.
Supported versions
Testfly accepts YAML or JSON specs in any of these versions:
| Version | Status | Notes |
|---|---|---|
| OpenAPI 3.1 | Full support | Recommended. Best schema fidelity |
| OpenAPI 3.0 | Full support | Most common. Widely supported by tools |
| Swagger 2.0 | Full support | Legacy format. Auto-converted internally |
Version is auto-detected from the spec content. You don't need to specify it.
Type mapping
OpenAPI types and formats map to database column types and data generation strategies:
| OpenAPI type | Format | DB type | Example value |
|---|---|---|---|
string | uuid | TEXT | 550e8400-e29b-... |
string | date-time | TEXT | 2026-01-15T14:30:00Z |
string | date | TEXT | 2025-11-22 |
string | email | TEXT | sarah.chen@example.com |
string | (none) | TEXT | Inferred from column name |
integer | int32 | INTEGER | 4271 |
integer | int64 | INTEGER | 9223372036854 |
number | float / double | REAL | 29.99 |
boolean | — | INTEGER | 0 or 1 |
Semantic data generation
Testfly infers the meaning of a column from its name and generates appropriate data:
| Column name contains | Generated as |
|---|---|
email | Realistic email addresses |
name, first_name, last_name | Human names |
phone | Phone numbers (+1 format) |
url, website | URLs |
price, amount, cost | Realistic decimal values |
address, street | Street addresses |
city | Real city names |
country | Country codes (US, CA, GB, ...) |
description, bio | Lorem ipsum text |
status | active, inactive, pending, completed |
Enum properties use values from the spec's enum array directly.
Schema composition
allOf (inheritance / merge)
All schemas in the allOf array are merged into a single resource:
Pet:
allOf:
- $ref: '#/components/schemas/BaseEntity'
- type: object
properties:
name: { type: string }
species: { type: string }
Result: One pets table with properties from both schemas.
oneOf / anyOf
Testfly takes the first variant as the canonical schema:
Payment:
oneOf:
- $ref: '#/components/schemas/CreditCardPayment'
- $ref: '#/components/schemas/BankTransferPayment'
Result: payments table uses CreditCardPayment schema.
Nested objects
Objects with 5 or fewer properties become a JSON TEXT column:
User:
properties:
address:
type: object
properties:
street: { type: string }
city: { type: string }
zip: { type: string }
Result: address stored as JSON in the users table.
Arrays
- Arrays of primitives → JSON TEXT column
- Arrays of objects → one-to-many relationship (separate table)
Foreign key detection
Three strategies, in priority order:
1. Property name convention
Properties ending in Id or _id are FK candidates:
Pet:
properties:
ownerId: # → FK to "owners" table
type: string
format: uuid
category_id: # → FK to "categories" table
type: integer
Guessed table names are validated against actual resources. Unmatched FKs are delegated to Cufflink's assembly-level detection.
2. $ref resolution
Properties referencing another schema via $ref are detected as FKs.
3. x-fk extension
assignee_id:
type: string
format: uuid
x-fk: "users.id"
Topological sorting
Resources are ordered so parent tables populate before children. Circular references are broken by making one FK nullable.
Vendor extensions
| Extension | Where | Description |
|---|---|---|
x-primary-key | Property | Mark as primary key (overrides auto-detection of id) |
x-fk | Property | Explicit FK: x-fk: "table.column" |
Route mapping
| Spec pattern | Generated operation |
|---|---|
GET /pets | List (paginated) |
GET /pets/{id} | Get by ID |
POST /pets | Create |
PUT /pets/{id} | Update |
PATCH /pets/{id} | Partial update |
DELETE /pets/{id} | Delete |
Resources with schemas but no explicit paths get default CRUD routes generated automatically.
Edge cases
Skipped schemas
- Schemas ending in
Responsewith ≤2 properties - Schemas ending in
Error
Auto-generated IDs
If no id property or x-primary-key exists, a UUID id is added automatically.
Table naming
OrderItem → order_items
User → users
Category → categorys
PascalCase → snake_case, auto-pluralized with trailing "s".
Have a complex spec?
Upload it and see what Testfly generates. If something doesn't look right, reach out.