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
id
property 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