Product
Enterprise
Solutions
DocumentationPricing
Resources
Book a DemoSign InGet Started
Product
Solutions
Solutions
Implementation Phase | API Mocking

API Mocking

9 min read

Eliminate development bottlenecks by creating functional mock APIs that enable frontend and backend teams to work simultaneously. Learn practical mocking strategies using the AI Prompt Enhancer project with real OpenAPI specifications, Prism setup, and CI/CD integration.

Cover image

API mocking creates a simulated version of your API that returns predefined responses. It acts like the real API but lacks business logic or database connections.

Think of API mocking as a movie set facade.

It looks like a real building from the front, but there's no structure behind it. The mock API similarly presents a realistic interface of endpoints that respond with sample data without actual implementation.

This approach lets you test integration patterns, validate API designs, and develop client applications while the backend team builds the real implementation.

Why Mock Your APIs

API mocking offers concrete benefits that directly impact development velocity:

  • Parallel development: Frontend and backend teams work simultaneously instead of sequentially
  • Early feedback: Identify design issues before writing any backend code, saving significant refactoring time
  • Faster testing: QA can test integration paths before the API is complete, catching workflow issues early
  • Better demos: Showcase functionality to stakeholders without waiting for full implementation
  • Consistent testing: Create reliable test environments with predictable data responses
  • Documentation validation: Verify your API documentation is accurate and complete by actually using it

Creating a Mock Server Using Your OpenAPI Specification

The best part about API mocking is that you can generate a fully functional mock using your existing OpenAPI Specification—no additional setup or configuration required.

Using Prism for Mock Generation

Prism is an open-source HTTP mock server that uses your OpenAPI document to create a functioning mock API.

Install Prism:

npm install -g @stoplight/prism-cli

Start the mock server:

prism mock openapi.yaml

That's it.

Your mock server is now responding to requests based on your OpenAPI document.

Testing with our AI Prompt Enhancer API:

# Start the mock server
prism mock openapi.yaml
 
# The server starts on port 4010 by default
# Mock server running at: http://127.0.0.1:4010

Now you can make requests to the mock API exactly as you would to the real API:

# Get a mock authentication token
curl -X POST "http://localhost:4010/v1/auth/tokens" \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "frontend-client",
    "clientSecret": "test_api_key"
  }'
 
# Response includes a realistic token structure:
# {
#   "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
#   "token_type": "Bearer",
#   "expires_in": 86400,
#   "scope": "api:access"
# }
 
# Use the token for prompt enhancement
curl -X POST "http://localhost:4010/v1/prompts" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Write about quantum computing",
    "format": "structured"
  }'

Prism responds based on the examples and schemas defined in your OpenAPI document, providing realistic data for development and testing.

Swagger UI Integration for Interactive Mocking

The AI Prompt Enhancer API uses Swagger UI for documentation and as an interactive API testing tool. Swagger UI becomes a powerful way to explore and test your API before implementation when connected to a mock server.

Here's how we configure Swagger UI to work with both mock and real APIs:

// Load OpenAPI specification with multiple server options
const swaggerUiOptions = {
    explorer: true,
    swaggerOptions: {
        // Allow users to choose between live and mock APIs
        urls: [
            { 
                url: '/docs-json', 
                name: 'Live API (Production)' 
            },
            { 
                url: 'http://localhost:4010/docs-json', 
                name: 'Mock API (Development)' 
            }
        ]
    },
    customCss: '.swagger-ui .topbar { display: none }',
};
 
app.use('/docs', swaggerUi.serve, swaggerUi.setup(null, swaggerUiOptions));

This configuration lets developers toggle between the live API and mock API directly from the Swagger UI interface, making it easy to test against either environment.

Customizing Mock Responses

Sometimes the default mocked responses aren't sufficient. You might need specific data for testing or want to simulate error scenarios.

Adding Examples in OpenAPI

The most effective way to customize mock responses is by adding examples in your OpenAPI specification. Here's how we define multiple response examples in our AI Prompt Enhancer API:

/prompts:
  post:
    responses:
      '200':
        description: Successfully enhanced prompt
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PromptResponse'
            examples:
              quantumComputing:
                value:
                  id: "prompt_abc123"
                  originalText: "Write about quantum computing"
                  enhancedText: "You are an expert-level content strategist..."
                  format: "structured"
                  createdAt: "2025-03-05T10:30:00Z"
              marketingPlan:
                value:
                  id: "prompt_def456"
                  originalText: "Create a marketing plan"
                  enhancedText: "Act as a senior marketing strategist..."
                  format: "structured"
                  createdAt: "2025-03-05T11:45:00Z"
      '400':
        description: Bad request - Invalid input
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Error'
            examples:
              missingText:
                value:
                  error:
                    code: "validation_error"
                    message: "The 'text' field is required"
                    details:
                      param: "text"
                      reason: "missing_required_field"
              invalidFormat:
                value:
                  error:
                    code: "invalid_parameter"
                    message: "The 'format' parameter must be one of: structured, paragraph, bullet, conversational"
                    details:
                      param: "format"
                      reason: "enum_violation"

With multiple examples defined, you can specify which example to use with query parameters:

# Get the marketing plan example
curl -X POST "http://localhost:4010/v1/prompts?__example=marketingPlan" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Any text here - the example will be returned regardless",
    "format": "structured"
  }'
 
# Trigger a validation error
curl -X POST "http://localhost:4010/v1/prompts?__code=400&__example=missingText" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{}'

This approach lets you test different scenarios and error conditions without complex mock server configuration.

Integrating Mock APIs with Frontend Development

Now that you have a mock API running, you can integrate it with your frontend development workflow.

Frontend Configuration for Mock Integration

For our AI Prompt Enhancer project, we configure the frontend to work with either the real or mock API through environment variables:

// Define API base URL based on environment
const API_BASE_URL = process.env.REACT_APP_API_URL ||
    (process.env.NODE_ENV === 'development'
        ? 'http://localhost:5000/v1'
        : 'https://prompt-enhancer.ai/v1');
 
// Allow override for mock API testing
const MOCK_API_URL = 'http://localhost:4010/v1';
const USE_MOCK = process.env.REACT_APP_USE_MOCK === 'true';
 
const apiUrl = USE_MOCK ? MOCK_API_URL : API_BASE_URL;
 
console.log('API Configuration:', {
    baseUrl: apiUrl,
    environment: process.env.NODE_ENV,
    usingMock: USE_MOCK
});

This setup allows frontend developers to toggle between the mock API and the real API:

# Use mock API for frontend development
REACT_APP_USE_MOCK=true npm start
 
# Use real API
REACT_APP_USE_MOCK=false npm start

Authentication Flow with Mock APIs

One of the most challenging aspects of frontend development is handling authentication. With a mock API, you can simulate the complete authentication flow using the actual code paths:

// Authentication service that works with both mock and real APIs
const authService = {
    async initializeAuth() {
        const apiKey = process.env.REACT_APP_API_KEY;
        
        try {
            const response = await fetch(`${apiUrl}/auth/tokens`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    clientId: 'frontend-client',
                    clientSecret: apiKey
                })
            });
            
            if (!response.ok) {
                throw new Error(`Authentication failed: ${response.status}`);
            }
            
            const data = await response.json();
            localStorage.setItem('auth_token', data.access_token);
            
            return data.access_token;
        } catch (error) {
            console.error('Authentication error:', error);
            throw error;
        }
    },
 
    async enhancePrompt(text, format = 'structured') {
        const token = localStorage.getItem('auth_token') || await this.initializeAuth();
        
        const response = await fetch(`${apiUrl}/prompts`, {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${token}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                text,
                format
            })
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error: ${response.status}`);
        }
        
        return response.json();
    }
};

This authentication flow works identically with mock and real APIs, allowing you to develop and test the complete user experience.

Testing Error Scenarios with Mock APIs

One of the most valuable aspects of mock APIs is the ability to test error scenarios that might be difficult to trigger with a real API.

Simulating Different Error Conditions

You can simulate various error scenarios using the examples defined in your OpenAPI specification:

# Test authentication failure
curl -X POST "http://localhost:4010/v1/auth/tokens?__code=401" \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "frontend-client",
    "clientSecret": "invalid_key"
  }'
 
# Test rate limiting
curl -X POST "http://localhost:4010/v1/prompts?__code=429" \
  -H "Authorization: Bearer token" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Test prompt",
    "format": "structured"
  }'
 
# Test validation errors
curl -X POST "http://localhost:4010/v1/prompts?__code=400&__example=missingText" \
  -H "Authorization: Bearer token" \
  -H "Content-Type: application/json" \
  -d '{}'

Testing Error Handling in Frontend Code

Once you can simulate errors, you can test how your frontend handles them:

const PromptEnhancer = () => {
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState(null);
    const [result, setResult] = useState(null);
 
    const handleSubmit = async (prompt) => {
        setIsLoading(true);
        setError(null);
        
        try {
            const enhancedPrompt = await authService.enhancePrompt(prompt);
            setResult(enhancedPrompt);
        } catch (err) {
            // Test error handling logic
            if (err.message.includes('401')) {
                setError("Authentication failed. Please try again.");
                // Clear stored token and retry authentication
                localStorage.removeItem('auth_token');
            } else if (err.message.includes('429')) {
                setError("Rate limit exceeded. Please try again later.");
                // Implement retry with backoff
            } else if (err.message.includes('400')) {
                setError("Invalid input. Please check your prompt and try again.");
            } else {
                setError("An unexpected error occurred. Please try again.");
            }
        } finally {
            setIsLoading(false);
        }
    };
 
    return (
        <div>
            {error && <div className="error">{error}</div>}
            {isLoading && <div>Processing...</div>}
            {result && <div className="result">{result.enhancedText}</div>}
        </div>
    );
};

This approach lets you thoroughly test error handling without relying on the backend to simulate specific failure conditions.

Transitioning from Mock to Real API

Eventually, you'll need to transition from mock to real API. The AI Prompt Enhancer project makes this transition smooth through environment-based configuration:

# Development with mock API
REACT_APP_API_URL=http://localhost:4010/v1
REACT_APP_USE_MOCK=true
 
# Development with real API
REACT_APP_API_URL=http://localhost:5000/v1
REACT_APP_USE_MOCK=false
 
# Production
REACT_APP_API_URL=https://prompt-enhancer.ai/v1
REACT_APP_USE_MOCK=false

You can easily switch between environments using different npm scripts:

{
  "scripts": {
    "start": "react-scripts start",
    "start:mock": "REACT_APP_USE_MOCK=true react-scripts start",
    "start:dev": "REACT_APP_API_URL=http://localhost:5000/v1 react-scripts start",
    "test:mock": "REACT_APP_USE_MOCK=true react-scripts test",
    "build:mock": "REACT_APP_USE_MOCK=true react-scripts build"
  }
}

This configuration approach ensures that switching between mock and real APIs requires no code changes, only environment variable updates.

Takeaways

API mocking transforms your development workflow by enabling:

  • Parallel development between the frontend and backend teams
  • Earlier feedback on API design through actual usage
  • Comprehensive testing of error scenarios and edge cases
  • Faster iteration on both API design and implementation

The key to successful API mocking is maintaining your OpenAPI specification with realistic examples and comprehensive error scenarios. This investment pays dividends throughout the development lifecycle.

© 2025 Treblle. All Rights Reserved.
GDPR BadgeSOC2 BadgeISO BadgeHIPAA Badge