FakeRestApi
A TypeScript library for creating fake REST APIs for testing and prototyping. Provides complete CRUD operations with pagination support and optional request delays.
🚀 Quick Start
import { createFakeRestApi } from '@codeleap/debug'
// Define your item type
type User = {
  id: number
  name: string
  email: string
  role: string
}
// Create the fake API
const usersApi = createFakeRestApi<User>({
  name: 'users',
  generatorFn: (id) => ({
    id,
    name: `User ${id}`,
    email: `user${id}@example.com`,
    role: 'user'
  })
})
// Use the API
const response = await usersApi.listItems(10, 0)
console.log(response.results) // Array with 10 users
🎯 Features
- ✅ Complete CRUD operations (Create, Read, Update, Delete)
 - ✅ Automatic pagination with next/previous URLs
 - ✅ Customizable filter system
 - ✅ Artificial delays to simulate network latency
 
📖 API Reference
createFakeRestApi<T, F>(options)
Factory function to create a new API instance.
Type Parameters:
T extends FakeItem- Type of items to manageF = Record<string, unknown>- Type of filters (optional)
Options:
{
  name: string              // API name (used in URLs and messages)
  generatorFn: (id) => T   // Function to generate new items
  maxCount?: number        // Maximum number of initial items (default: 100)
  enableDelay?: boolean    // Enable artificial delay (default: false)
  delayMs?: number         // Delay duration in ms (default: 2500)
  filterFn?: (item, filters) => boolean  // Custom filter function
}
Instance Methods
listItems(limit?, offset?, filters?)
Returns a paginated list of items.
const response = await api.listItems(10, 0)
// Returns: PaginationResponse<T>
Response:
{
  count: number           // Total number of items
  next: string | null     // URL for next page
  previous: string | null // URL for previous page
  results: T[]           // Array of items for current page
}
retrieveItem(id)
Fetches a single item by ID.
const user = await api.retrieveItem(5)
createItem(item?)
Creates a new item.
const newUser = await api.createItem({
  name: 'John Doe',
  email: 'john@example.com',
  role: 'admin'
})
updateItem(id, updates)
Updates an existing item.
const updated = await api.updateItem(5, {
  role: 'admin'
})
deleteItem(id)
Removes an item by ID.
const deleted = await api.deleteItem(5)
reset()
Resets data to initial state.
api.reset()
clear()
Removes all items.
api.clear()
getData()
Returns a readonly copy of all items.
const allItems = api.getData()
getItem(id)
Fetches an item by ID without delay (synchronous).
const user = api.getItem(5)
generateItem(id?)
Generates a new item using the generator function.
const newItem = api.generateItem(101)
setOptions(newOptions)
Partially updates API options.
api.setOptions({ enableDelay: true, delayMs: 1000 })
Properties
name: string- API namecount: number- Current number of items
💡 Advanced Examples
With Custom Filters
type Product = {
  id: number
  name: string
  category: string
  price: number
}
type ProductFilters = {
  category?: string
  minPrice?: number
  maxPrice?: number
}
const productsApi = createFakeRestApi<Product, ProductFilters>({
  name: 'products',
  maxCount: 200,
  generatorFn: (id) => ({
    id,
    name: `Product ${id}`,
    category: ['electronics', 'clothing', 'books'][id % 3],
    price: Math.random() * 1000
  }),
  filterFn: (item, filters) => {
    if (filters.category && item.category !== filters.category) {
      return false
    }
    if (filters.minPrice && item.price < filters.minPrice) {
      return false
    }
    if (filters.maxPrice && item.price > filters.maxPrice) {
      return false
    }
    return true
  }
})
// Fetch filtered products
const electronics = await productsApi.listItems(10, 0, {
  category: 'electronics',
  minPrice: 100,
  maxPrice: 500
})
Simulating Network Latency
const api = createFakeRestApi<User>({
  name: 'users',
  enableDelay: true,
  delayMs: 1500, // 1.5 seconds delay
  generatorFn: (id) => ({
    id,
    name: `User ${id}`,
    email: `user${id}@example.com`
  })
})
// All operations will now have a 1.5s delay
await api.listItems() // Takes ~1.5s
await api.retrieveItem(1) // Takes ~1.5s
React Integration
import { useState, useEffect } from 'react'
import { createFakeRestApi } from '@codeleap/debug'
const api = createFakeRestApi<User>({
  name: 'users',
  maxCount: 100,
  generatorFn: (id) => ({
    id,
    name: `User ${id}`,
    email: `user${id}@example.com`
  })
})
function UserList() {
  const [users, setUsers] = useState([])
  const [loading, setLoading] = useState(true)
  useEffect(() => {
    api.listItems(20, 0).then(response => {
      setUsers(response.results)
      setLoading(false)
    })
  }, [])
  if (loading) return <div>Loading...</div>
  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  )
}
🔍 Use Cases
- Frontend Development: Work on the frontend before the backend is ready
 - Prototyping: Create prototypes quickly without setting up a server
 - Testing: Write tests without depending on external APIs
 - Demos: Create functional demos without infrastructure
 
📝 Types
type FakeItem = {
  id: number
}
type PaginationResponse<T> = {
  count: number
  next: string | null
  previous: string | null
  results: T[]
}
type FakeRestApiOptions<T extends FakeItem, F> = {
  name: string
  generatorFn: (id: T['id']) => T
  enableDelay?: boolean
  maxCount?: number
  delayMs?: number
  filterFn?: (item: T, filters: F) => boolean
}
⚠️ Important Notes
- All items must have an 
idproperty of typenumber - The ID is always auto-incremented and cannot be modified
 - Data is stored in memory and is lost on page reload
 - The library does not persist data - it's only for development and testing
 - Pagination URLs are just formatted strings, they are not functional