Mocker API for RESTful Development
mocker-api is a development utility designed for mocking RESTful APIs, facilitating frontend development by enabling work independent of a live backend. It supports flexible integration as middleware with common development servers like Express.js and webpack-dev-server. The current stable version is 4.0.0, which has updated its Node.js requirement to `>=16.0.0`. The library features hot module replacement for mock files, allows quick API configuration via JSON or JavaScript files, and provides simple mock API proxying. It also offers first-class TypeScript type definitions for an enhanced developer experience. Unlike some other mocking solutions, `mocker-api` can be used independently without relying on a full webpack setup, making it versatile for various project types, including Create React App. It helps streamline development workflows by providing predictable API responses during the early stages of a project.
Common errors
-
TypeError: (0 , _mockerApi.default) is not a function
cause This error typically occurs when attempting to import an ESM module using a CommonJS `require()` syntax, or when a bundler incorrectly transpiles ESM to CJS, expecting a `.default` property on the imported module.fixEnsure you are using ESM `import apiMocker from 'mocker-api';` syntax. If using CommonJS, check your `tsconfig.json` (for TypeScript) or Babel configuration to ensure correct module resolution and transpilation for ESM packages. For Node.js, ensure your environment supports ESM or use a tool like `ts-node` with appropriate settings. -
Error: Cannot find module 'express'
cause The `express` package is a common dependency for `mocker-api` usage, especially when integrating it into an Express.js application, but it might be a peer dependency or simply an assumed external dependency, not automatically installed by `mocker-api` itself.fixInstall `express` as a dependency in your project: `npm install express` or `yarn add express`. -
Error: Mock file path '/path/to/nonexistent/mocker/index.js' is invalid or mock data is not an an object or function.
cause The `apiMocker` function expects a valid path to a JavaScript/TypeScript file that exports an object or a function containing your mock definitions, or it expects a direct mock object. This error indicates the file was not found, or its export was not in the expected format.fixVerify that the path provided to `apiMocker` (e.g., `path.resolve(__dirname, 'mocker/index.js')`) correctly points to an existing file, and that the file exports either an object of mock definitions or a function that returns such an object. Ensure the file is accessible and free of syntax errors. -
Error: EADDRINUSE: address already in use :::8080
cause This error occurs when the port specified for the Express server (e.g., 8080) is already being used by another application or process on your system.fixChange the `port` variable in your `app.listen()` call to an available port (e.g., 3000, 8000, 9000). You can also use tools like `lsof -i :8080` (macOS/Linux) or `netstat -ano | findstr :8080` (Windows) to identify and terminate the process using the port, if appropriate.
Warnings
- breaking Version 4.0.0 introduces a stricter Node.js engine requirement. Projects running on Node.js versions older than 16.0.0 will encounter compatibility issues due to updated runtime dependencies and features.
- breaking Upgrading from `mocker-api` v2.x or v3.x to v4.0.0 may involve significant breaking changes due to potential API refactorings, option removals, or changes in internal concepts. Many libraries use major versions to remove deprecated 'legacy' APIs introduced in previous minors.
- gotcha When using `mocker-api` with Express, the order of middleware is crucial. If `mocker-api` middleware is placed after other route handlers, those handlers might intercept requests before the mocker has a chance to respond, leading to unexpected behavior or unmocked responses. Conversely, if proxying is enabled, ensure `mocker-api` is positioned correctly to allow proxies to function without conflicting with other static file servers.
- gotcha Defining complex mock logic directly within a single large mock file can become unmanageable. While `mocker-api` supports dynamic functions as mock responses, over-complicating these can obscure the API contract and make debugging difficult. Also, ensure mock file paths are correctly resolved, especially in different build environments.
Install
-
npm install mocker-api -
yarn add mocker-api -
pnpm add mocker-api
Imports
- apiMocker
const apiMocker = require('mocker-api');import apiMocker from 'mocker-api';
- MockerAPIOptions
import type { MockerAPIOptions } from 'mocker-api'; - MockDefinition
// In mocker/index.ts: interface User { id: number; name: string; } const mocks: Record<string, User | User[]> = { 'GET /api/users': [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }], 'GET /api/user/:id': (req, res) => { const id = parseInt(req.params.id, 10); if (id === 1) return res.json({ id: 1, name: 'Alice' }); if (id === 2) return res.json({ id: 2, name: 'Bob' }); res.status(404).json({ message: 'User not found' }); }, }; export default mocks;
Quickstart
import express from 'express';
import path from 'path';
import apiMocker from 'mocker-api';
interface User { id: number; name: string; email: string; }
// --- Create 'mocker/index.ts' file in your project root or source directory ---
// const mocks = {
// 'GET /api/users': [
// { id: 1, name: 'Alice', email: 'alice@example.com' },
// { id: 2, name: 'Bob', email: 'bob@example.com' },
// ],
// 'POST /api/users': (req, res) => {
// const newUser: User = { id: Date.now(), ...req.body };
// console.log('New user created:', newUser);
// res.status(201).json(newUser);
// },
// 'GET /api/user/:id': (req, res) => {
// const userId = parseInt(req.params.id, 10);
// const users: User[] = [
// { id: 1, name: 'Alice', email: 'alice@example.com' },
// { id: 2, name: 'Bob', email: 'bob@example.com' },
// ];
// const user = users.find(u => u.id === userId);
// if (user) {
// res.json(user);
// } else {
// res.status(404).json({ message: `User with ID ${userId} not found` });
// }
// },
// 'GET /api/posts': [
// { id: 101, title: 'First Post' },
// { id: 102, title: 'Second Post' },
// ],
// // Example of proxying specific requests: anything starting with /github/
// 'GET /github/*': 'https://api.github.com/',
// };
// export default mocks;
// -----------------------------------------------------------------------------
const app = express();
const port = process.env.PORT ?? 8080; // Use process.env.PORT or default to 8080
// Enable JSON body parsing for POST/PUT requests (essential for 'POST /api/users' mock)
app.use(express.json());
// Resolve the path to your mock definition file.
// Ensure 'mocker/index.js' or 'mocker/index.ts' exists and exports the mock definitions.
const mockDirectory = path.resolve(__dirname, 'mocker/index.js'); // Adjust for your build output
apiMocker(app, mockDirectory, {
// Optional: Enable proxying for unmocked routes. Requests matching '/api/(.*)'
// that are not explicitly mocked will be forwarded to JSONPlaceholder.
proxy: {
'/api/(.*)': 'https://jsonplaceholder.typicode.com/',
},
// Set changeHost to true when proxying to external hosts like GitHub API to avoid CORS issues.
changeHost: true,
// Optional: Simulate network delay for all mock responses in milliseconds.
delay: 500,
});
app.listen(port, () => {
console.log(`Mock API Server is running at http://localhost:${port}`);
console.log('Try visiting:');
console.log(`- http://localhost:${port}/api/users (mocked data from 'mocker/index.ts')`);
console.log(`- http://localhost:${port}/api/user/1 (mocked data from 'mocker/index.ts')`);
console.log(`- http://localhost:${port}/api/todos/1 (proxied to JSONPlaceholder)`);
console.log(`- http://localhost:${port}/github/users/jaywcjlove (proxied to GitHub API)`);
});