Skip to content

daniyalibrar/apimocker

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

33 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ApiMocker πŸš€

A comprehensive fake REST API service for developers to test against, built with Node.js, Express, TypeScript, and PostgreSQL. Features include rate limiting, validation, realistic data, and advanced filtering capabilities.

Live Demo: https://apimocker.com

You can test it out with my API probe tool - https://apiprobe.dev

⚑ Quick Usage (Hosted)

  • Hosted Base URL: https://apimocker.com
  • All responses are JSON and support pagination, filtering, and sorting.

Core Endpoints

  • Users
    • GET https://apimocker.com/users
    • GET https://apimocker.com/users/1
    • GET https://apimocker.com/users/1/posts
    • GET https://apimocker.com/users/1/todos
    • GET https://apimocker.com/users/search?q=john
  • Posts
    • GET https://apimocker.com/posts
    • GET https://apimocker.com/posts/1
    • GET https://apimocker.com/posts?userId=1&_page=1&_limit=10
    • GET https://apimocker.com/posts/search?q=development&_sort=id&_order=desc&_page=1&_limit=5
  • Todos
    • GET https://apimocker.com/todos
    • GET https://apimocker.com/todos/1
    • GET https://apimocker.com/todos?completed=true&_page=1&_limit=10
    • GET https://apimocker.com/todos/search?q=review
  • Comments
    • GET https://apimocker.com/comments
    • GET https://apimocker.com/comments/1
    • GET https://apimocker.com/comments?postId=1&_page=1&_limit=5
    • GET https://apimocker.com/comments/search?q=great

Useful Query Params

  • Pagination: _page, _limit
  • Sorting: _sort, _order (e.g., _sort=title&_order=asc)
  • Text search: field_like (e.g., title_like=web)
  • Response delay (simulate latency): _delay=2000

Health Check

  • GET https://apimocker.com/health

✨ Features

  • Full CRUD Operations - Create, Read, Update, Delete for all resources
  • PATCH Method Support - Partial updates for posts and todos
  • Advanced Filtering - _like, _sort, _order parameters with X-Total-Count headers
  • Global Search - Search across all resources with type filtering
  • Response Delay Simulation - _delay parameter for testing loading states
  • Error Simulation - Dedicated endpoints for testing error handling
  • Realistic Data - 10 users, 100 posts, 200 todos, 500 comments with realistic content
  • Rate Limiting - Configurable limits to prevent abuse
  • Input Validation - Comprehensive validation for all endpoints
  • Pagination - Built-in pagination support with _page and _limit
  • Daily Reset - Automatic database reset at midnight UTC
  • Comprehensive Logging - Request/response logging with Winston
  • TypeScript - Full type safety throughout the application
  • Prisma ORM - Type-safe database operations
  • Neon PostgreSQL - Cloud-hosted database

πŸ›  Tech Stack

  • Backend: Node.js, Express.js
  • Language: TypeScript
  • Database: PostgreSQL (Neon)
  • ORM: Prisma
  • Validation: express-validator
  • Rate Limiting: express-rate-limit
  • Logging: Winston
  • Security: Helmet, CORS
  • Scheduling: node-cron

πŸš€ Quick Start

Prerequisites

  • Node.js 18+
  • npm or yarn
  • Neon PostgreSQL database

Installation

  1. Clone the repository

    git clone <repository-url>
    cd apimocker
  2. Install dependencies

    npm install
  3. Set up environment variables Create a .env file in the root directory:

    # Database
    DATABASE_URL="postgresql://username:password@host/database?sslmode=require"
    
    # Server
    PORT=8000
    NODE_ENV=development
    
    # Rate Limiting
    RATE_LIMIT_WINDOW_MS=86400000 # 24 hours
    RATE_LIMIT_MAX_WRITES=100 # 100 writes per day per IP
    
    # Logging
    LOG_LEVEL=info
  4. Generate Prisma client

    npm run db:generate
  5. Push database schema

    npm run db:push
  6. Seed the database

    npm run db:seed
  7. Start the server

    npm run dev

The API will be available at http://localhost:8000

πŸ“Š API Endpoints

Base URL

http://localhost:8000

Web Interface

http://localhost:8000/

A beautiful web interface with API documentation and quick testing links.

API Base URL

http://localhost:8000/api

πŸ” Advanced Features

Global Search

Search across all resources with the global search endpoint:

GET /search?q=development&type=posts

Parameters:

  • q (required): Search query
  • type (optional): Resource type (users, posts, todos, comments, all)
  • _delay (optional): Response delay in milliseconds

Response Delay Simulation

Test loading states by adding delays to any request:

GET /posts?_delay=2000

Error Simulation

Test error handling with dedicated error endpoints:

GET /error/404
GET /error/500
GET /error/validation
GET /error/timeout

Health Check

GET /health

Response:

{
  "status": "OK",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "uptime": 3600
}

Users

Get All Users

GET /users

Query Parameters:

  • _page (optional): Page number (default: 1)
  • _limit (optional): Items per page (default: 10, max: 100)

Example:

GET /users?_page=1&_limit=5

Response:

{
  "data": [
    {
      "id": 1,
      "name": "John Doe",
      "username": "johndoe",
      "email": "[email protected]",
      "phone": "+1-555-0123",
      "website": "https://johndoe.dev",
      "address": {
        "street": "123 Main St",
        "suite": "Apt 4B",
        "city": "New York",
        "zipcode": "10001",
        "geo": { "lat": "40.7128", "lng": "-74.0060" }
      },
      "company": {
        "name": "Tech Solutions Inc",
        "catchPhrase": "Innovating the future",
        "bs": "harness real-time e-markets"
      },
      "createdAt": "2024-01-15T10:30:00.000Z",
      "updatedAt": "2024-01-15T10:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 5,
    "total": 10,
    "totalPages": 2,
    "hasNext": true,
    "hasPrev": false
  }
}

Get User by ID

GET /users/:id

Example:

GET /users/1

Create User

POST /users
Content-Type: application/json

Request Body:

{
  "name": "New User",
  "username": "newuser",
  "email": "[email protected]",
  "phone": "+1-555-0123",
  "website": "https://newuser.com",
  "address": {
    "street": "123 Main St",
    "suite": "Apt 4B",
    "city": "New York",
    "zipcode": "10001",
    "geo": { "lat": "40.7128", "lng": "-74.0060" }
  },
  "company": {
    "name": "Company Name",
    "catchPhrase": "Company catchphrase",
    "bs": "Company business statement"
  }
}

Update User

PUT /users/:id
Content-Type: application/json

Example:

PUT /users/1
{
  "name": "Updated Name"
}

Delete User

DELETE /users/:id

Example:

DELETE /users/1

Get User's Posts

GET /users/:id/posts

Query Parameters:

  • _page (optional): Page number (default: 1)
  • _limit (optional): Items per page (default: 10)

Example:

GET /users/1/posts?_page=1&_limit=5

Get User's Todos

GET /users/:id/todos

Query Parameters:

  • _page (optional): Page number (default: 1)
  • _limit (optional): Items per page (default: 10)

Example:

GET /users/1/todos?_page=1&_limit=5

Posts

Get All Posts

GET /posts

Query Parameters:

  • _page (optional): Page number (default: 1)
  • _limit (optional): Items per page (default: 10)
  • userId (optional): Filter by user ID

Example:

GET /posts?userId=1&_page=1&_limit=5

Response:

{
  "data": [
    {
      "id": 1,
      "title": "Getting Started with Modern Web Development",
      "body": "This is a comprehensive article about getting started with modern web development...",
      "userId": 1,
      "user": {
        "id": 1,
        "name": "John Doe",
        "username": "johndoe",
        "email": "[email protected]"
      },
      "createdAt": "2024-01-15T10:30:00.000Z",
      "updatedAt": "2024-01-15T10:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 5,
    "total": 100,
    "totalPages": 20,
    "hasNext": true,
    "hasPrev": false
  }
}

Get Post by ID

GET /posts/:id

Create Post

POST /posts
Content-Type: application/json

Request Body:

{
  "title": "New Post Title",
  "body": "This is the content of the new post..."
}

Note: userId is optional and defaults to user ID 1 if not provided.

Update Post

PUT /posts/:id
Content-Type: application/json

Delete Post

DELETE /posts/:id

Todos

Get All Todos

GET /todos

Query Parameters:

  • _page (optional): Page number (default: 1)
  • _limit (optional): Items per page (default: 10)
  • userId (optional): Filter by user ID
  • completed (optional): Filter by completion status (true/false)

Example:

GET /todos?completed=true&userId=1&_page=1&_limit=5

Response:

{
  "data": [
    {
      "id": 1,
      "title": "Review pull requests",
      "completed": true,
      "userId": 1,
      "user": {
        "id": 1,
        "name": "John Doe",
        "username": "johndoe",
        "email": "[email protected]"
      },
      "createdAt": "2024-01-15T10:30:00.000Z",
      "updatedAt": "2024-01-15T10:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 5,
    "total": 200,
    "totalPages": 40,
    "hasNext": true,
    "hasPrev": false
  }
}

Get Todo by ID

GET /todos/:id

Create Todo

POST /todos
Content-Type: application/json

Request Body:

{
  "title": "New Todo Item",
  "description": "Optional description for the todo item",
  "completed": false
}

Note: userId and description are optional. userId defaults to user ID 1 if not provided.

Update Todo

PUT /todos/:id
Content-Type: application/json

Delete Todo

DELETE /todos/:id

Comments

Get All Comments

GET /comments

Query Parameters:

  • _page (optional): Page number (default: 1)
  • _limit (optional): Items per page (default: 10)
  • postId (optional): Filter by post ID
  • name_like (optional): Search by commenter name
  • email_like (optional): Search by email

Example:

GET /comments?postId=1&_page=1&_limit=5

Response:

{
  "data": [
    {
      "id": 1,
      "name": "John Doe",
      "email": "[email protected]",
      "body": "Great article! This really helped me understand the concepts better.",
      "postId": 1,
      "post": {
        "id": 1,
        "title": "Getting Started with Modern Web Development"
      },
      "createdAt": "2024-01-15T10:30:00.000Z",
      "updatedAt": "2024-01-15T10:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 5,
    "total": 500,
    "totalPages": 100,
    "hasNext": true,
    "hasPrev": false
  }
}

Get Comment by ID

GET /comments/:id

Create Comment

POST /comments
Content-Type: application/json

Request Body:

{
  "name": "Commenter Name",
  "email": "[email protected]",
  "body": "This is a comment on the post",
  "postId": 1
}

Update Comment

PUT /comments/:id
Content-Type: application/json

Delete Comment

DELETE /comments/:id

πŸ” Advanced Filtering & Querying

ApiMocker supports powerful filtering, sorting, and querying capabilities:

Pagination

  • _page or page: Page number (default: 1)
  • _limit or limit: Items per page (default: 10, max: 100)

Sorting

  • _sort: Field to sort by (e.g., title, id, createdAt)
  • _order: Sort order (asc or desc)

Text Search

  • field_like: Partial text matching (case-insensitive)
    • title_like=web - Search posts with "web" in title
    • name_like=john - Search users with "john" in name
    • body_like=development - Search posts with "development" in body

Response Headers

  • X-Total-Count: Total number of items (for pagination)

Examples

Basic pagination:

GET /posts?_page=2&_limit=5

Sorting:

GET /posts?_sort=title&_order=asc

Text search:

GET /posts?title_like=development

Combined filtering:

GET /todos?completed=true&userId=1&_sort=title&_order=desc&_page=1&_limit=10

With delay simulation:

GET /posts?title_like=web&_delay=2000

πŸ”’ Rate Limiting

ApiMocker implements a sophisticated rate limiting system to prevent abuse while allowing legitimate usage:

Write Operations (POST, PUT, DELETE, PATCH)

  • Limit: 100 write operations per day per IP address
  • Window: 24 hours (configurable via RATE_LIMIT_WINDOW_MS)
  • Reset: Daily at midnight UTC

Read Operations (GET)

  • Limit: 1000 requests per 15 minutes per IP address
  • Window: 15 minutes
  • Reset: Automatically after the time window

Rate Limit Response

When rate limits are exceeded, the API returns:

{
  "error": "Too Many Requests",
  "message": "Write limit exceeded. Maximum 100 write operations per day per IP.",
  "resetTime": "2024-01-16T00:00:00.000Z"
}

HTTP Status: 429 Too Many Requests

Rate Limit Headers

The API includes rate limit information in response headers:

  • X-RateLimit-Limit: Maximum requests allowed
  • X-RateLimit-Remaining: Remaining requests in current window
  • X-RateLimit-Reset: Time when the rate limit resets

βœ… Input Validation

All endpoints include comprehensive input validation:

User Validation

  • name: Required, 1-100 characters
  • username: Required, 3-50 characters, alphanumeric + underscore only
  • email: Required, valid email format
  • phone: Optional, valid phone number
  • website: Optional, valid URL
  • address: Optional, must be an object
  • company: Optional, must be an object

Post Validation

  • title: Required, 1-200 characters
  • body: Required, 1-5000 characters
  • userId: Optional, positive integer (defaults to user ID 1 if not provided)

Todo Validation

  • title: Required, 1-200 characters
  • description: Optional, 1-1000 characters
  • completed: Optional, boolean value
  • userId: Optional, positive integer (defaults to user ID 1 if not provided)

Validation Error Response

{
  "error": "Validation Error",
  "message": "Invalid input data",
  "details": [
    {
      "type": "field",
      "value": "",
      "msg": "Name is required and must be between 1 and 100 characters",
      "path": "name",
      "location": "body"
    }
  ]
}

πŸ”„ Daily Reset

The database automatically resets at midnight UTC every day:

  • All existing data is cleared
  • Fresh seed data is inserted
  • 10 users, 100 posts, and 200 todos are created
  • Reset includes realistic data with proper relationships

This ensures a consistent testing environment and prevents data accumulation.

πŸ“ Logging

ApiMocker uses Winston for comprehensive logging:

Log Files

  • logs/error.log: Error-level logs only
  • logs/combined.log: All logs

Logged Information

  • Request Details: Method, URL, IP, User-Agent, timestamp
  • Response Details: Status code, duration, content length
  • Error Details: Stack traces, error messages
  • Database Operations: Connection status, seeding events

Log Format

{
  "level": "info",
  "message": "Request completed",
  "method": "GET",
  "url": "/users",
  "statusCode": 200,
  "duration": "45ms",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "service": "apimocker"
}

πŸ›  Development Scripts

# Development
npm run dev          # Start development server
npm run build        # Build TypeScript
npm run start        # Start production server

# Database
npm run db:generate  # Generate Prisma client
npm run db:push      # Push schema to database
npm run db:seed      # Seed database with sample data
npm run db:reset     # Reset and reseed database
npm run db:studio    # Open Prisma Studio

# Testing
npm test             # Run all tests
npm run test:watch   # Run tests in watch mode
npm run test:coverage # Run tests with coverage
npm run test:integration # Run only integration tests
npm run test:unit    # Run only unit tests

πŸ“ Project Structure

apimocker/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ controllers/
β”‚   β”‚   └── genericController.ts    # Generic CRUD controller
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”œβ”€β”€ errorHandler.ts         # Error handling middleware
β”‚   β”‚   β”œβ”€β”€ rateLimiter.ts          # Rate limiting middleware
β”‚   β”‚   β”œβ”€β”€ requestLogger.ts        # Request logging middleware
β”‚   β”‚   └── validation.ts           # Input validation middleware
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”œβ”€β”€ users.ts                # User routes
β”‚   β”‚   β”œβ”€β”€ posts.ts                # Post routes
β”‚   β”‚   └── todos.ts                # Todo routes
β”‚   β”œβ”€β”€ scripts/
β”‚   β”‚   β”œβ”€β”€ seed.ts                 # Database seeding
β”‚   β”‚   └── reset.ts                # Database reset
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   β”œβ”€β”€ logger.ts               # Winston logger configuration
β”‚   β”‚   └── cronJobs.ts             # Daily reset scheduling
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   └── prisma.ts               # Prisma client initialization
β”‚   └── index.ts                    # Main application file
β”œβ”€β”€ prisma/
β”‚   └── schema.prisma               # Database schema
β”œβ”€β”€ logs/                           # Log files (auto-generated)
β”œβ”€β”€ .env                            # Environment variables
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
└── README.md

πŸ”§ Configuration

Environment Variables

Variable Description Default
DATABASE_URL PostgreSQL connection string Required
PORT Server port 8000
NODE_ENV Environment (development/production) development
RATE_LIMIT_WINDOW_MS Rate limit window in milliseconds 86400000 (24h)
RATE_LIMIT_MAX_WRITES Maximum write operations per day per IP 100
LOG_LEVEL Logging level (error, warn, info, debug) info

Database Schema

The application uses three main models:

  • User: Personal information, contact details, address, company
  • Post: Blog posts with title, body, and user relationship
  • Todo: Task items with title, completion status, and user relationship

All models include timestamps and proper foreign key relationships.

πŸš€ Deployment

Production Deployment

  1. Set environment variables

    NODE_ENV=production
    DATABASE_URL=your_production_database_url
  2. Build the application

    npm run build
  3. Start the server

    npm start

Docker Deployment (Optional)

FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

EXPOSE 8000

CMD ["npm", "start"]

πŸ§ͺ Testing

ApiMocker includes a comprehensive testing suite with both integration and unit tests.

Quick Start

  1. Set up test environment:

    # Create test database
    createdb apimocker_test
    
    # Set up test environment variables
    cp .env.example .env.test
    # Edit .env.test with test database URL
  2. Run tests:

    # Run all tests
    npm test
    
    # Run with coverage
    npm run test:coverage
    
    # Run specific test types
    npm run test:integration
    npm run test:unit

Test Types

  • Integration Tests: Full API endpoint testing with real database operations
  • Unit Tests: Individual component testing with mocked dependencies
  • Manual Testing: Example scripts for manual API testing

Test Coverage

The test suite covers:

  • βœ… All CRUD operations for Users, Posts, and Todos
  • βœ… Pagination and filtering
  • βœ… Input validation and error handling
  • βœ… Rate limiting enforcement
  • βœ… Database relationships
  • βœ… Edge cases and boundary conditions

For detailed testing information, see tests/README.md.

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

πŸ“„ License

This project is licensed under the MIT License.

πŸ†˜ Support

For issues, questions, or contributions:

  • Create an issue on GitHub
  • Check the documentation
  • Review the API endpoints

ApiMocker - Your reliable fake API for development and testing! 🎯

About

Fake REST api with persistence

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 73.7%
  • HTML 16.3%
  • JavaScript 8.0%
  • CSS 2.0%