Core ConceptsOpenAPI Integration

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/:postId

This 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'

Next Steps

  • Combine with Factories for custom data generation
  • Use with Scenarios for complete test setups
  • See Examples for real-world OpenAPI usage