OpenAPI Integration
MockMaster can automatically generate realistic mock data from OpenAPI 3.0 specifications.
Overview
OpenAPI integration enables you to:
- Parse JSON and YAML OpenAPI 3.0 specs
- Generate realistic mock data from schemas
- Extract all operations and endpoints
- Create scenarios automatically
This approach ensures:
- Schema compliance - Mocks match your API contract
- Type safety - Generated data follows schema types
- Rapid development - No manual mock creation
- Consistency - Same schema, same mocks
Parsing OpenAPI Specs
Parse YAML
import { parseYaml } from '@mockmaster/openapi'
const spec = parseYaml(`
openapi: 3.0.0
info:
title: User API
version: 1.0.0
paths:
/users:
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
type: object
properties:
id: { type: integer }
name: { type: string }
email: { type: string, format: email }
`)Parse JSON
import { parseSpec } from '@mockmaster/openapi'
const spec = parseSpec({
openapi: '3.0.0',
info: {
title: 'User API',
version: '1.0.0'
},
paths: {
'/users': {
get: {
responses: {
'200': {
content: {
'application/json': {
schema: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' },
email: { type: 'string', format: 'email' }
}
}
}
}
}
}
}
}
}
}
})Load from File
import { readFileSync } from 'fs'
import { parseYaml, parseSpec } from '@mockmaster/openapi'
// YAML file
const yamlContent = readFileSync('./openapi.yaml', 'utf-8')
const yamlSpec = parseYaml(yamlContent)
// JSON file
const jsonContent = readFileSync('./openapi.json', 'utf-8')
const jsonSpec = parseSpec(JSON.parse(jsonContent))Generating Mock Data
From Schema
Generate mock data directly from a schema:
import { generateFromSchema } from '@mockmaster/openapi'
const schema = {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' },
email: { type: 'string', format: 'email' },
age: { type: 'integer', minimum: 18, maximum: 80 },
isActive: { type: 'boolean' }
},
required: ['id', 'name', 'email']
}
const user = generateFromSchema(schema)
console.log(user)
// {
// id: 1,
// name: 'John Doe',
// email: 'john.doe@example.com',
// age: 42,
// isActive: true
// }Array Schemas
const schema = {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' }
}
}
}
const users = generateFromSchema(schema)
// [
// { id: 1, name: 'John Doe' },
// { id: 2, name: 'Jane Smith' }
// ]Generating Scenarios
From Entire Spec
Generate scenarios for all operations in the spec:
import { generateScenariosFromSpec } from '@mockmaster/cli'
import { parseYaml } from '@mockmaster/openapi'
const spec = parseYaml(`
openapi: 3.0.0
info:
title: User API
version: 1.0.0
paths:
/users:
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
type: object
properties:
id: { type: integer }
name: { type: string }
/users/{id}:
get:
responses:
'200':
content:
application/json:
schema:
type: object
properties:
id: { type: integer }
name: { type: string }
email: { type: string }
`)
const scenarios = generateScenariosFromSpec(spec, 'user-api')
// Generates recordings for:
// - GET /users
// - GET /users/{id}Save Generated Scenarios
import { writeScenario } from '@mockmaster/cli'
for (const scenario of scenarios) {
await writeScenario('./scenarios', scenario)
}Path Parameter Format Conversion
MockMaster automatically converts OpenAPI path format ({id}) to Express/router format (:id):
// OpenAPI spec uses {id} format
paths:
/users/{id}:
get: ...
/users/{userId}/posts/{postId}:
get: ...
// Generated scenarios use :id format for routing
// GET /users/:id
// GET /users/:userId/posts/:postIdThis conversion ensures compatibility with Express, MSW, and other routing libraries while keeping the original URL format for documentation.
DELETE and 204 No Content Support
MockMaster fully supports DELETE operations and 204 No Content responses:
const spec = parseYaml(`
openapi: 3.0.0
paths:
/users/{id}:
delete:
responses:
'204':
description: 'User deleted successfully'
`)
const scenarios = generateScenariosFromSpec(spec, 'user-api')
// Generated recording:
// - Method: DELETE
// - Path: /users/:id
// - Status: 204
// - Body: null
// - Headers: {} (no Content-Type for 204)204 responses and other responses without content (like some 201 Created responses) are properly handled with null body and appropriate headers.
Schema Types Support
MockMaster supports all OpenAPI schema types:
String Types
{
type: 'string' // 'John Doe'
type: 'string', format: 'email' // 'john@example.com'
type: 'string', format: 'uri' // 'https://example.com'
type: 'string', format: 'date' // '2024-01-15'
type: 'string', format: 'date-time' // '2024-01-15T10:30:00Z'
type: 'string', format: 'uuid' // '123e4567-e89b-12d3-a456-426614174000'
}Number Types
{
type: 'integer' // 42
type: 'number' // 3.14
type: 'integer', minimum: 18, maximum: 80 // 35
type: 'number', minimum: 0, maximum: 1 // 0.567
}Boolean Type
{
type: 'boolean' // true or false
}Array Type
{
type: 'array',
items: { type: 'string' } // ['item1', 'item2', 'item3']
}Object Type
{
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' }
}
}
// { id: 1, name: 'John Doe' }Enum Type
{
type: 'string',
enum: ['active', 'inactive', 'pending']
}
// Randomly selects: 'active'Complex Schemas
Nested Objects
const schema = {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' },
address: {
type: 'object',
properties: {
street: { type: 'string' },
city: { type: 'string' },
zipCode: { type: 'string' }
}
}
}
}
const data = generateFromSchema(schema)
// {
// id: 1,
// name: 'John Doe',
// address: {
// street: '123 Main St',
// city: 'New York',
// zipCode: '10001'
// }
// }Arrays of Objects
const schema = {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'integer' },
title: { type: 'string' },
tags: {
type: 'array',
items: { type: 'string' }
}
}
}
}
const data = generateFromSchema(schema)
// [
// { id: 1, title: 'Post 1', tags: ['tag1', 'tag2'] },
// { id: 2, title: 'Post 2', tags: ['tag3', 'tag4'] }
// ]References ($ref)
const spec = {
openapi: '3.0.0',
components: {
schemas: {
User: {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' }
}
}
}
},
paths: {
'/users': {
get: {
responses: {
'200': {
content: {
'application/json': {
schema: {
type: 'array',
items: { $ref: '#/components/schemas/User' }
}
}
}
}
}
}
}
}
}
// MockMaster automatically resolves references
const scenarios = generateScenariosFromSpec(parseSpec(spec), 'user-api')Extracting Operations
Get all operations from a spec:
import { getAllOperations } from '@mockmaster/openapi'
const operations = getAllOperations(spec)
operations.forEach(op => {
console.log(`${op.method} ${op.path}`)
console.log(` operationId: ${op.operationId}`)
console.log(` summary: ${op.summary}`)
console.log(` responses:`, Object.keys(op.responses))
})
// Output:
// GET /users
// operationId: listUsers
// summary: List all users
// responses: ['200']
// GET /users/{id}
// operationId: getUser
// summary: Get user by ID
// responses: ['200', '404']Real-World Examples
E-commerce API
openapi: 3.0.0
info:
title: E-commerce API
version: 1.0.0
paths:
/products:
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
type: object
properties:
id: { type: integer }
name: { type: string }
price: { type: number, minimum: 0 }
category: { type: string }
inStock: { type: boolean }
/cart:
post:
requestBody:
content:
application/json:
schema:
type: object
properties:
productId: { type: integer }
quantity: { type: integer, minimum: 1 }
responses:
'201':
content:
application/json:
schema:
type: object
properties:
id: { type: integer }
items: {
type: array,
items: {
type: object,
properties: {
productId: { type: integer }
quantity: { type: integer }
price: { type: number }
}
}
}
total: { type: number }Blog API
openapi: 3.0.0
info:
title: Blog API
version: 1.0.0
paths:
/posts:
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
type: object
properties:
id: { type: integer }
title: { type: string }
body: { type: string }
author: { type: string }
publishedAt: { type: string, format: date-time }
tags: {
type: array,
items: { type: string }
}Best Practices
1. Use Detailed Schemas
Provide detailed schemas with constraints:
properties:
age:
type: integer
minimum: 18
maximum: 100
email:
type: string
format: email
pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'2. Leverage Formats
Use OpenAPI formats for realistic data:
properties:
email: { type: string, format: email }
url: { type: string, format: uri }
createdAt: { type: string, format: date-time }
uuid: { type: string, format: uuid }3. Define Reusable Schemas
Use components for reusable schemas:
components:
schemas:
User:
type: object
properties:
id: { type: integer }
name: { type: string }
paths:
/users:
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'4. Document Examples
Add examples to your schemas:
properties:
status:
type: string
enum: ['active', 'inactive', 'pending']
example: 'active'