Mock Servers with Prism

Learn how to use Prism to create mock API servers for parallel frontend development

Mock Servers with Prism

Overview

Prism creates mock API servers from your OpenAPI specification, enabling frontend developers to work in parallel with backend development. No database required!

What is a Mock Server?

A mock server:

  • ✅ Implements all endpoints from your OpenAPI spec
  • ✅ Generates realistic fake data based on schemas
  • ✅ Returns example responses
  • ✅ Validates requests
  • ✅ Simulates error responses
  • ✅ Enables parallel frontend/backend development

Quick Start

1. Start Mock Server

./scripts/start-prism.sh

Output:

Starting Prism mock server...
Starting mock server on port 3334...
Using spec: src/openapi.json

Mock server features:
   - Dynamic response generation from schemas
   - Example responses from OpenAPI spec
   - Request validation
   - CORS enabled

Mock API available at: http://localhost:3334

2. Test Mock Endpoint

# Get mock users
curl http://localhost:3334/user

# Create mock user
curl -X POST http://localhost:3334/user \
  -H "Content-Type: application/json" \
  -d '{"name": "John Doe", "email": "john@example.com"}'

3. Use in Frontend

// Configure API base URL
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3334';

// Fetch mock data
const response = await fetch(`${API_URL}/user`);
const users = await response.json();

Mock Server Features

Dynamic Data Generation

Prism generates realistic data based on your schemas:

# OpenAPI Schema
User:
  properties:
    id:
      type: integer
    name:
      type: string
    email:
      type: string
      format: email
    age:
      type: integer
      minimum: 18
      maximum: 100

Mock response:

{
  "id": 42,
  "name": "John Smith",
  "email": "john.smith@example.com",
  "age": 35
}

Example Responses

If your OpenAPI spec includes examples, Prism uses them:

paths:
  /user:
    get:
      responses:
        '200':
          content:
            application/json:
              example:
                - id: 1
                  name: "Alice Johnson"
                  email: "alice@example.com"
                - id: 2
                  name: "Bob Williams"
                  email: "bob@example.com"

Prism returns your exact examples!

Request Validation

Prism validates requests against your schema:

# Invalid request (missing required field)
curl -X POST http://localhost:3334/user \
  -H "Content-Type: application/json" \
  -d '{"name": "John"}'

# Response:
{
  "error": "Validation failed",
  "details": [
    {
      "field": "email",
      "message": "Required field missing"
    }
  ]
}

Error Simulation

Prism can simulate error responses:

# Request with invalid ID format
curl http://localhost:3334/user/invalid-id

# Response:
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Invalid ID format"
}

Configuration

Custom Port

MOCK_PORT=4000 ./scripts/start-prism.sh

Custom Spec Location

API_DIR=dist ./scripts/start-prism.sh

Environment Variables

# .env.local (Next.js)
NEXT_PUBLIC_API_URL=http://localhost:3334

# .env.development (Vite)
VITE_API_URL=http://localhost:3334

# .env (Angular)
NG_APP_API_URL=http://localhost:3334

Use Cases

1. Frontend Development Before Backend

Scenario: Backend API not ready yet.

Solution:

  1. Design OpenAPI spec together
  2. Run databridge generate to create spec
  3. Start Prism mock server
  4. Frontend builds against mock
  5. Switch to real API when ready!
// Switch between mock and real API
const API_URL = process.env.NODE_ENV === 'development'
  ? 'http://localhost:3334'  // Mock
  : 'https://api.production.com';  // Real

2. Frontend/Backend Parallel Development

Team A: Backend developers build real API
Team B: Frontend developers use mock API

No waiting! Both teams work simultaneously.

3. Demo/Prototype Without Database

Scenario: Need to demo UI without setting up database.

# No database needed!
./scripts/start-prism.sh

# Show working UI with mock data
npm run dev

4. Integration Tests Without DB

// Cypress test with mock API
describe('User Management', () => {
  before(() => {
    // Start Prism before tests
    cy.exec('./scripts/start-prism.sh &');
  });

  it('loads users from mock API', () => {
    cy.visit('/users');
    cy.get('.user-card').should('have.length.gt', 0);
  });
});

5. Onboarding New Developers

New developer setup:

git clone repo
npm install
./scripts/start-prism.sh  # No DB setup!
npm run dev

UI works immediately with mock data!

Frontend Integration Examples

React

// hooks/useAPI.ts
const API_BASE = import.meta.env.VITE_API_URL || 'http://localhost:3334';

export function useUsers() {
  const [users, setUsers] = useState([]);
  
  useEffect(() => {
    fetch(`${API_BASE}/user`)
      .then(res => res.json())
      .then(setUsers);
  }, []);
  
  return users;
}

// Usage
function UserList() {
  const users = useUsers();  // Works with mock or real API!
  return <>{users.map(user => <UserCard key={user.id} {...user} />)}</>;
}

Vue 3

<script setup>
import { ref, onMounted } from 'vue';

const API_BASE = import.meta.env.VITE_API_URL || 'http://localhost:3334';
const users = ref([]);

onMounted(async () => {
  const res = await fetch(`${API_BASE}/user`);
  users.value = await res.json();
});
</script>

<template>
  <div v-for="user in users" :key="user.id">
    {{ user.name }}
  </div>
</template>

Angular

// environment.ts
export const environment = {
  production: false,
  apiUrl: 'http://localhost:3334'
};

// user.service.ts
@Injectable()
export class UserService {
  private apiUrl = environment.apiUrl;
  
  getUsers() {
    return this.http.get<User[]>(`${this.apiUrl}/user`);
  }
}

Next.js

// app/users/page.tsx
export default async function UsersPage() {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3334';
  const res = await fetch(`${apiUrl}/user`);
  const users = await res.json();
  
  return <UserList users={users} />;
}

Advanced Features

Prefer Examples Over Generated Data

prism mock src/openapi.json --dynamic=false

Uses only examples from spec, doesn’t generate fake data.

Enable Request Logging

prism mock src/openapi.json --dynamic --verbose

Shows all incoming requests and responses.

Simulate Slow Responses

# Add delay to responses (milliseconds)
prism mock src/openapi.json --dynamic --delay=1000

Tests loading states in your UI!

Specific Error Rates

Not built into Prism CLI, but you can use a proxy:

// mock-proxy.js
const express = require('express');
const proxy = require('express-http-proxy');

const app = express();

app.use('/api', proxy('http://localhost:3334', {
  userResFilter: (proxyRes, proxyResData) => {
    // 10% chance of 500 error
    if (Math.random() < 0.1) {
      proxyRes.statusCode = 500;
      return JSON.stringify({ error: 'Server Error' });
    }
    return proxyResData;
  }
}));

app.listen(4000);

Prism vs Real API

FeaturePrism MockReal API
Setup TimeInstantHours/Days
DatabaseNot neededRequired
Data PersistenceNo (resets each call)Yes
Custom LogicNo (schema-based only)Yes
PerformanceVery fastDepends
Production ReadyNoYes

Workflow Comparison

Without Mock Server

Backend Dev → API Ready → Frontend Dev → Integration
   ↓ 2 weeks    ↓ 1 day      ↓ 2 weeks       ↓ 3 days
   
Total: 4+ weeks, sequential

With Mock Server

Backend Dev    ─┐
   ↓ 2 weeks    ├→ Integration
                │    ↓ 1 day
Frontend Dev   ─┘
   ↓ 2 weeks (parallel!)

Total: 2-3 weeks, parallel

Time Saved: 40-50%

Troubleshooting

Prism Not Starting

# Check if port is in use
lsof -i :3334

# Use different port
MOCK_PORT=4000 ./scripts/start-prism.sh

No Data Returned

# Check OpenAPI spec is valid
./scripts/validate-openapi.sh

# Check schemas have types defined
cat src/openapi.json | jq '.components.schemas'

CORS Errors

Prism enables CORS by default. If still having issues:

# Explicitly enable CORS
prism mock src/openapi.json --dynamic --cors

Wrong Data Types

Check your OpenAPI schema types:

# Wrong
id: string  # Should be integer

# Correct
id:
  type: integer
  format: int32

Best Practices

1. Add Examples to OpenAPI Spec

User:
  type: object
  example:
    id: 1
    name: "Jane Doe"
    email: "jane@example.com"

2. Document Mock Server in README

## Development

### With Mock API (no database)
\`\`\`bash
./scripts/start-prism.sh
npm run dev
\`\`\`

### With Real API
\`\`\`bash
docker-compose up -d  # Start MySQL
npm run api:dev       # Start real API
npm run dev           # Start frontend
\`\`\`

3. Environment Variable Switching

# .env.example
API_URL=http://localhost:3334  # Default to mock

4. Document Limitations

## Mock Server Limitations
- No data persistence
- No authentication
- No custom business logic
- For development only

Next Steps

Resources


Need help? Open an issue on GitHub

Was this page helpful?