Mock HTTP server for testing HTTP clients and stubbing webservices
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Fluent rule builder system for matching and mocking HTTP requests with comprehensive matching capabilities including method, path, headers, body content, and custom logic.
Methods for creating HTTP request matchers with various HTTP methods and patterns.
interface Mockttp {
/**
* Match any HTTP request (excludes WebSockets).
* Use for catch-all rules or complex custom matching.
*/
forAnyRequest(): RequestRuleBuilder;
/**
* Match requests that don't match any other rules.
* Lower priority fallback rule for unhandled requests.
*/
forUnmatchedRequest(): RequestRuleBuilder;
/**
* Match GET requests for the given URL pattern.
* URL can be string path, full URL, or regular expression.
*/
forGet(url?: string | RegExp): RequestRuleBuilder;
/**
* Match POST requests for the given URL pattern.
*/
forPost(url?: string | RegExp): RequestRuleBuilder;
/**
* Match PUT requests for the given URL pattern.
*/
forPut(url?: string | RegExp): RequestRuleBuilder;
/**
* Match DELETE requests for the given URL pattern.
*/
forDelete(url?: string | RegExp): RequestRuleBuilder;
/**
* Match PATCH requests for the given URL pattern.
*/
forPatch(url?: string | RegExp): RequestRuleBuilder;
/**
* Match HEAD requests for the given URL pattern.
*/
forHead(url?: string | RegExp): RequestRuleBuilder;
/**
* Match OPTIONS requests for the given URL pattern.
* Requires cors: false option as CORS auto-handles OPTIONS by default.
*/
forOptions(url?: string | RegExp): RequestRuleBuilder;
/**
* Match JSON-RPC requests with optional method and parameter matching.
* Looks for jsonrpc: '2.0' in request body plus optional method/params.
*/
forJsonRpcRequest(match?: {method?: string, params?: any}): RequestRuleBuilder;
}Usage Examples:
import { getLocal } from "mockttp";
const mockServer = getLocal();
await mockServer.start();
// Basic method matching
await mockServer.forGet("/api/users").thenReply(200, []);
await mockServer.forPost("/api/users").thenReply(201, { id: 1 });
// URL patterns
await mockServer.forGet("/api/users/*").thenReply(200, { user: "data" });
await mockServer.forGet(/\/api\/users\/\d+/).thenReply(200, { id: 123 });
// Full URL matching
await mockServer.forGet("http://api.example.com/users").thenReply(200, []);
// Catch-all rules
await mockServer.forAnyRequest().thenReply(404, "Not Found");
await mockServer.forUnmatchedRequest().thenReply(500, "Unexpected request");
// JSON-RPC matching
await mockServer.forJsonRpcRequest({
method: "getUserById",
params: { id: 123 }
}).thenReply(200, { jsonrpc: "2.0", result: { name: "Alice" } });Fluent methods for matching request properties beyond URL and method.
interface RequestRuleBuilder {
/**
* Match requests with specific HTTP method.
*/
withMethod(method: Method): this;
/**
* Match requests with specific path (string or regex).
*/
withPath(path: string | RegExp): this;
/**
* Match requests with exact path string.
*/
withExactPath(path: string): this;
/**
* Match requests with specific query parameters.
* Partial matching - only specified params need to match.
*/
withQuery(query: {[key: string]: string | string[] | undefined}): this;
/**
* Match requests with exact query string.
*/
withExactQuery(query: string): this;
/**
* Match requests containing specified headers.
* Partial matching - only specified headers need to match.
*/
withHeaders(headers: Headers): this;
/**
* Match requests with a specific header value.
* Value can be string or regex pattern.
*/
withHeader(name: string, value: string | RegExp): this;
/**
* Match requests with exact body content.
* Can be string, Buffer, or object (JSON).
*/
withBody(body: string | Buffer | {[key: string]: any}): this;
/**
* Match requests with body as UTF-8 text.
*/
withBodyText(body: string): this;
/**
* Match requests where body contains the specified text.
*/
withBodyIncluding(body: string): this;
/**
* Match requests with exact JSON body.
*/
withJsonBody(body: object): this;
/**
* Match requests where JSON body contains specified fields.
* Partial matching - only specified fields need to match.
*/
withJsonBodyIncluding(body: object): this;
/**
* Match requests with form data (URL-encoded).
*/
withForm(form: {[key: string]: string | string[] | undefined}): this;
/**
* Match requests with specific form field value.
*/
withFormField(name: string, value: string | RegExp): this;
/**
* Match requests with multipart form data.
*/
withMultipartForm(form: MultipartFieldMatchCondition[]): this;
/**
* Match requests with specific cookie values.
*/
withCookie(cookie: {[key: string]: string}): this;
/**
* Match requests to specific hostname.
*/
withHostname(hostname: string | RegExp): this;
/**
* Match requests to specific host (hostname:port).
*/
withHost(host: string | RegExp): this;
/**
* Match requests to specific host (hostname:port).
* Alternative method name for withHost.
*/
forHost(host: string): this;
/**
* Match requests to specific hostname only.
* Alternative method name for withHostname.
*/
forHostname(hostname: string): this;
/**
* Match requests on specific port number.
*/
withPort(port: number): this;
/**
* Match requests on specific port number.
* Alternative method name for withPort.
*/
forPort(port: number): this;
/**
* Match requests with specific protocol (http/https).
*/
withProtocol(protocol: "http" | "https" | "ws" | "wss"): this;
/**
* Match requests where URL matches regular expression.
*/
withUrlMatching(pattern: RegExp): this;
/**
* Match requests using custom logic function.
* Function receives completed request and returns boolean or Promise<boolean>.
*/
matching(callback: (request: CompletedRequest) => boolean | Promise<boolean>): this;
}
interface MultipartFieldMatchCondition {
name: string;
value?: string | RegExp;
filename?: string | RegExp;
headers?: Headers;
}
interface Headers {
[key: string]: undefined | string | string[];
}
enum Method {
GET,
POST,
PUT,
DELETE,
PATCH,
HEAD,
OPTIONS
}Usage Examples:
import { getLocal } from "mockttp";
const mockServer = getLocal();
await mockServer.start();
// Header matching
await mockServer.forPost("/api/data")
.withHeader("content-type", "application/json")
.withHeader("authorization", /^Bearer .+/)
.thenReply(200, { success: true });
// Query parameter matching
await mockServer.forGet("/api/search")
.withQuery({ q: "test", limit: "10" })
.thenReply(200, { results: [] });
// JSON body matching
await mockServer.forPost("/api/users")
.withJsonBodyIncluding({
email: "user@example.com",
role: "admin"
})
.thenReply(201, { id: 123, created: true });
// Form data matching
await mockServer.forPost("/login")
.withForm({
username: "alice",
password: "secret123"
})
.thenReply(200, { token: "jwt-token" });
// Custom matching logic
await mockServer.forAnyRequest()
.matching((req) => {
return req.headers['x-api-key'] === 'secret-key' &&
req.url.includes('/premium/');
})
.thenReply(200, { premium: true });
// Complex multipart form
await mockServer.forPost("/upload")
.withMultipartForm([
{ name: "file", filename: /\.(jpg|png)$/ },
{ name: "title", value: "Profile Picture" }
])
.thenReply(200, { uploaded: true });Methods for controlling when and how many times rules are executed.
interface RequestRuleBuilder {
/**
* Rule completes after matching 1 request (default behavior).
*/
once(): this;
/**
* Rule completes after matching 2 requests.
*/
twice(): this;
/**
* Rule completes after matching 3 requests.
*/
thrice(): this;
/**
* Rule completes after matching n requests.
*/
times(n: number): this;
/**
* Rule never completes automatically, matches indefinitely.
*/
always(): this;
}Usage Examples:
import { getLocal } from "mockttp";
const mockServer = getLocal();
await mockServer.start();
// Default behavior - matches once then completes
await mockServer.forGet("/api/config").thenReply(200, { version: "1.0" });
// Match exactly twice
await mockServer.forPost("/api/retry")
.twice()
.thenReply(503, "Service Unavailable");
// Match 5 times then complete
await mockServer.forGet("/api/limited")
.times(5)
.thenReply(200, { data: "limited access" });
// Match indefinitely
await mockServer.forGet("/health")
.always()
.thenReply(200, { status: "OK" });Methods for controlling rule matching priority and precedence.
interface RequestRuleBuilder {
/**
* Set rule priority level.
*/
withPriority(priority: RulePriority): this;
/**
* Alias for withPriority.
*/
asPriority(priority: RulePriority): this;
}
enum RulePriority {
FALLBACK = 0,
DEFAULT = 1
}Usage Examples:
import { getLocal, RulePriority } from "mockttp";
const mockServer = getLocal();
await mockServer.start();
// High priority rule matches first
await mockServer.forGet("/api/special")
.withPriority(RulePriority.DEFAULT)
.thenReply(200, { special: true });
// Fallback rule only matches if no other rules match
await mockServer.forAnyRequest()
.asPriority(RulePriority.FALLBACK)
.thenReply(404, "Not Found");Methods for controlling request processing timing and delays.
interface RequestRuleBuilder {
/**
* Add a delay in milliseconds before processing the request.
* Useful for simulating slow server responses.
*/
delay(ms: number): this;
}Usage Examples:
import { getLocal } from "mockttp";
const mockServer = getLocal();
await mockServer.start();
// Add 2 second delay before responding
await mockServer.forGet("/api/slow")
.delay(2000)
.thenReply(200, { data: "slow response" });
// Combine with multiple delays
await mockServer.forPost("/api/process")
.delay(1000) // 1 second processing delay
.thenReply(202, { status: "accepted" });Advanced methods for adding rules programmatically rather than using the fluent builder API.
interface Mockttp {
/**
* Add multiple HTTP request rules to the server.
* For advanced use cases requiring programmatic rule construction.
*/
addRequestRules(...ruleData: RequestRuleData[]): Promise<MockedEndpoint[]>;
/**
* Add a single HTTP request rule to the server.
* Convenience method for addRequestRules with one rule.
*/
addRequestRule(ruleData: RequestRuleData): Promise<MockedEndpoint>;
/**
* Replace all existing HTTP request rules with the given rules.
* WebSocket rules are left untouched.
*/
setRequestRules(...ruleData: RequestRuleData[]): Promise<MockedEndpoint[]>;
}
interface RequestRuleData {
// Rule data structure for manual rule construction
// Complex internal format - use fluent builders when possible
}Usage Examples:
import { getLocal } from "mockttp";
const mockServer = getLocal();
await mockServer.start();
// Typically you would use the fluent API instead:
const endpoint = await mockServer.forGet("/api/test").thenReply(200, "OK");
// But manual rule management enables advanced scenarios:
const rules = [
// ... manually constructed RequestRuleData objects
];
const endpoints = await mockServer.setRequestRules(...rules);Mockttp supports flexible URL matching patterns:
Relative Paths: /api/users - matches path only, ignoring host and protocol
Host + Path: api.example.com/users - matches host and path, any protocol
Full URLs: https://api.example.com/users - matches complete URL
Regular Expressions: /^\/api\/users\/\d+$/ - flexible pattern matching
Wildcards: /api/users/* - simple wildcard patterns
Query parameters are always ignored in URL matching. Use withQuery() or withExactQuery() to match query parameters.
Rules are matched in this order:
Within the same priority level, rules are matched in the order they were added.