0
# HTTP Request Mocking
1
2
Fluent rule builder system for matching and mocking HTTP requests with comprehensive matching capabilities including method, path, headers, body content, and custom logic.
3
4
## Capabilities
5
6
### Request Rule Builders
7
8
Methods for creating HTTP request matchers with various HTTP methods and patterns.
9
10
```typescript { .api }
11
interface Mockttp {
12
/**
13
* Match any HTTP request (excludes WebSockets).
14
* Use for catch-all rules or complex custom matching.
15
*/
16
forAnyRequest(): RequestRuleBuilder;
17
18
/**
19
* Match requests that don't match any other rules.
20
* Lower priority fallback rule for unhandled requests.
21
*/
22
forUnmatchedRequest(): RequestRuleBuilder;
23
24
/**
25
* Match GET requests for the given URL pattern.
26
* URL can be string path, full URL, or regular expression.
27
*/
28
forGet(url?: string | RegExp): RequestRuleBuilder;
29
30
/**
31
* Match POST requests for the given URL pattern.
32
*/
33
forPost(url?: string | RegExp): RequestRuleBuilder;
34
35
/**
36
* Match PUT requests for the given URL pattern.
37
*/
38
forPut(url?: string | RegExp): RequestRuleBuilder;
39
40
/**
41
* Match DELETE requests for the given URL pattern.
42
*/
43
forDelete(url?: string | RegExp): RequestRuleBuilder;
44
45
/**
46
* Match PATCH requests for the given URL pattern.
47
*/
48
forPatch(url?: string | RegExp): RequestRuleBuilder;
49
50
/**
51
* Match HEAD requests for the given URL pattern.
52
*/
53
forHead(url?: string | RegExp): RequestRuleBuilder;
54
55
/**
56
* Match OPTIONS requests for the given URL pattern.
57
* Requires cors: false option as CORS auto-handles OPTIONS by default.
58
*/
59
forOptions(url?: string | RegExp): RequestRuleBuilder;
60
61
/**
62
* Match JSON-RPC requests with optional method and parameter matching.
63
* Looks for jsonrpc: '2.0' in request body plus optional method/params.
64
*/
65
forJsonRpcRequest(match?: {method?: string, params?: any}): RequestRuleBuilder;
66
}
67
```
68
69
**Usage Examples:**
70
71
```typescript
72
import { getLocal } from "mockttp";
73
74
const mockServer = getLocal();
75
await mockServer.start();
76
77
// Basic method matching
78
await mockServer.forGet("/api/users").thenReply(200, []);
79
await mockServer.forPost("/api/users").thenReply(201, { id: 1 });
80
81
// URL patterns
82
await mockServer.forGet("/api/users/*").thenReply(200, { user: "data" });
83
await mockServer.forGet(/\/api\/users\/\d+/).thenReply(200, { id: 123 });
84
85
// Full URL matching
86
await mockServer.forGet("http://api.example.com/users").thenReply(200, []);
87
88
// Catch-all rules
89
await mockServer.forAnyRequest().thenReply(404, "Not Found");
90
await mockServer.forUnmatchedRequest().thenReply(500, "Unexpected request");
91
92
// JSON-RPC matching
93
await mockServer.forJsonRpcRequest({
94
method: "getUserById",
95
params: { id: 123 }
96
}).thenReply(200, { jsonrpc: "2.0", result: { name: "Alice" } });
97
```
98
99
### Request Matching
100
101
Fluent methods for matching request properties beyond URL and method.
102
103
```typescript { .api }
104
interface RequestRuleBuilder {
105
/**
106
* Match requests with specific HTTP method.
107
*/
108
withMethod(method: Method): this;
109
110
/**
111
* Match requests with specific path (string or regex).
112
*/
113
withPath(path: string | RegExp): this;
114
115
/**
116
* Match requests with exact path string.
117
*/
118
withExactPath(path: string): this;
119
120
/**
121
* Match requests with specific query parameters.
122
* Partial matching - only specified params need to match.
123
*/
124
withQuery(query: {[key: string]: string | string[] | undefined}): this;
125
126
/**
127
* Match requests with exact query string.
128
*/
129
withExactQuery(query: string): this;
130
131
/**
132
* Match requests containing specified headers.
133
* Partial matching - only specified headers need to match.
134
*/
135
withHeaders(headers: Headers): this;
136
137
/**
138
* Match requests with a specific header value.
139
* Value can be string or regex pattern.
140
*/
141
withHeader(name: string, value: string | RegExp): this;
142
143
/**
144
* Match requests with exact body content.
145
* Can be string, Buffer, or object (JSON).
146
*/
147
withBody(body: string | Buffer | {[key: string]: any}): this;
148
149
/**
150
* Match requests with body as UTF-8 text.
151
*/
152
withBodyText(body: string): this;
153
154
/**
155
* Match requests where body contains the specified text.
156
*/
157
withBodyIncluding(body: string): this;
158
159
/**
160
* Match requests with exact JSON body.
161
*/
162
withJsonBody(body: object): this;
163
164
/**
165
* Match requests where JSON body contains specified fields.
166
* Partial matching - only specified fields need to match.
167
*/
168
withJsonBodyIncluding(body: object): this;
169
170
/**
171
* Match requests with form data (URL-encoded).
172
*/
173
withForm(form: {[key: string]: string | string[] | undefined}): this;
174
175
/**
176
* Match requests with specific form field value.
177
*/
178
withFormField(name: string, value: string | RegExp): this;
179
180
/**
181
* Match requests with multipart form data.
182
*/
183
withMultipartForm(form: MultipartFieldMatchCondition[]): this;
184
185
/**
186
* Match requests with specific cookie values.
187
*/
188
withCookie(cookie: {[key: string]: string}): this;
189
190
/**
191
* Match requests to specific hostname.
192
*/
193
withHostname(hostname: string | RegExp): this;
194
195
/**
196
* Match requests to specific host (hostname:port).
197
*/
198
withHost(host: string | RegExp): this;
199
200
/**
201
* Match requests to specific host (hostname:port).
202
* Alternative method name for withHost.
203
*/
204
forHost(host: string): this;
205
206
/**
207
* Match requests to specific hostname only.
208
* Alternative method name for withHostname.
209
*/
210
forHostname(hostname: string): this;
211
212
/**
213
* Match requests on specific port number.
214
*/
215
withPort(port: number): this;
216
217
/**
218
* Match requests on specific port number.
219
* Alternative method name for withPort.
220
*/
221
forPort(port: number): this;
222
223
/**
224
* Match requests with specific protocol (http/https).
225
*/
226
withProtocol(protocol: "http" | "https" | "ws" | "wss"): this;
227
228
/**
229
* Match requests where URL matches regular expression.
230
*/
231
withUrlMatching(pattern: RegExp): this;
232
233
/**
234
* Match requests using custom logic function.
235
* Function receives completed request and returns boolean or Promise<boolean>.
236
*/
237
matching(callback: (request: CompletedRequest) => boolean | Promise<boolean>): this;
238
}
239
240
interface MultipartFieldMatchCondition {
241
name: string;
242
value?: string | RegExp;
243
filename?: string | RegExp;
244
headers?: Headers;
245
}
246
247
interface Headers {
248
[key: string]: undefined | string | string[];
249
}
250
251
enum Method {
252
GET,
253
POST,
254
PUT,
255
DELETE,
256
PATCH,
257
HEAD,
258
OPTIONS
259
}
260
```
261
262
**Usage Examples:**
263
264
```typescript
265
import { getLocal } from "mockttp";
266
267
const mockServer = getLocal();
268
await mockServer.start();
269
270
// Header matching
271
await mockServer.forPost("/api/data")
272
.withHeader("content-type", "application/json")
273
.withHeader("authorization", /^Bearer .+/)
274
.thenReply(200, { success: true });
275
276
// Query parameter matching
277
await mockServer.forGet("/api/search")
278
.withQuery({ q: "test", limit: "10" })
279
.thenReply(200, { results: [] });
280
281
// JSON body matching
282
await mockServer.forPost("/api/users")
283
.withJsonBodyIncluding({
284
email: "user@example.com",
285
role: "admin"
286
})
287
.thenReply(201, { id: 123, created: true });
288
289
// Form data matching
290
await mockServer.forPost("/login")
291
.withForm({
292
username: "alice",
293
password: "secret123"
294
})
295
.thenReply(200, { token: "jwt-token" });
296
297
// Custom matching logic
298
await mockServer.forAnyRequest()
299
.matching((req) => {
300
return req.headers['x-api-key'] === 'secret-key' &&
301
req.url.includes('/premium/');
302
})
303
.thenReply(200, { premium: true });
304
305
// Complex multipart form
306
await mockServer.forPost("/upload")
307
.withMultipartForm([
308
{ name: "file", filename: /\.(jpg|png)$/ },
309
{ name: "title", value: "Profile Picture" }
310
])
311
.thenReply(200, { uploaded: true });
312
```
313
314
### Rule Execution Control
315
316
Methods for controlling when and how many times rules are executed.
317
318
```typescript { .api }
319
interface RequestRuleBuilder {
320
/**
321
* Rule completes after matching 1 request (default behavior).
322
*/
323
once(): this;
324
325
/**
326
* Rule completes after matching 2 requests.
327
*/
328
twice(): this;
329
330
/**
331
* Rule completes after matching 3 requests.
332
*/
333
thrice(): this;
334
335
/**
336
* Rule completes after matching n requests.
337
*/
338
times(n: number): this;
339
340
/**
341
* Rule never completes automatically, matches indefinitely.
342
*/
343
always(): this;
344
}
345
```
346
347
**Usage Examples:**
348
349
```typescript
350
import { getLocal } from "mockttp";
351
352
const mockServer = getLocal();
353
await mockServer.start();
354
355
// Default behavior - matches once then completes
356
await mockServer.forGet("/api/config").thenReply(200, { version: "1.0" });
357
358
// Match exactly twice
359
await mockServer.forPost("/api/retry")
360
.twice()
361
.thenReply(503, "Service Unavailable");
362
363
// Match 5 times then complete
364
await mockServer.forGet("/api/limited")
365
.times(5)
366
.thenReply(200, { data: "limited access" });
367
368
// Match indefinitely
369
await mockServer.forGet("/health")
370
.always()
371
.thenReply(200, { status: "OK" });
372
```
373
374
### Rule Priority Control
375
376
Methods for controlling rule matching priority and precedence.
377
378
```typescript { .api }
379
interface RequestRuleBuilder {
380
/**
381
* Set rule priority level.
382
*/
383
withPriority(priority: RulePriority): this;
384
385
/**
386
* Alias for withPriority.
387
*/
388
asPriority(priority: RulePriority): this;
389
}
390
391
enum RulePriority {
392
FALLBACK = 0,
393
DEFAULT = 1
394
}
395
```
396
397
**Usage Examples:**
398
399
```typescript
400
import { getLocal, RulePriority } from "mockttp";
401
402
const mockServer = getLocal();
403
await mockServer.start();
404
405
// High priority rule matches first
406
await mockServer.forGet("/api/special")
407
.withPriority(RulePriority.DEFAULT)
408
.thenReply(200, { special: true });
409
410
// Fallback rule only matches if no other rules match
411
await mockServer.forAnyRequest()
412
.asPriority(RulePriority.FALLBACK)
413
.thenReply(404, "Not Found");
414
```
415
416
### Request Processing Control
417
418
Methods for controlling request processing timing and delays.
419
420
```typescript { .api }
421
interface RequestRuleBuilder {
422
/**
423
* Add a delay in milliseconds before processing the request.
424
* Useful for simulating slow server responses.
425
*/
426
delay(ms: number): this;
427
}
428
```
429
430
**Usage Examples:**
431
432
```typescript
433
import { getLocal } from "mockttp";
434
435
const mockServer = getLocal();
436
await mockServer.start();
437
438
// Add 2 second delay before responding
439
await mockServer.forGet("/api/slow")
440
.delay(2000)
441
.thenReply(200, { data: "slow response" });
442
443
// Combine with multiple delays
444
await mockServer.forPost("/api/process")
445
.delay(1000) // 1 second processing delay
446
.thenReply(202, { status: "accepted" });
447
```
448
449
### Manual Rule Management
450
451
Advanced methods for adding rules programmatically rather than using the fluent builder API.
452
453
```typescript { .api }
454
interface Mockttp {
455
/**
456
* Add multiple HTTP request rules to the server.
457
* For advanced use cases requiring programmatic rule construction.
458
*/
459
addRequestRules(...ruleData: RequestRuleData[]): Promise<MockedEndpoint[]>;
460
461
/**
462
* Add a single HTTP request rule to the server.
463
* Convenience method for addRequestRules with one rule.
464
*/
465
addRequestRule(ruleData: RequestRuleData): Promise<MockedEndpoint>;
466
467
/**
468
* Replace all existing HTTP request rules with the given rules.
469
* WebSocket rules are left untouched.
470
*/
471
setRequestRules(...ruleData: RequestRuleData[]): Promise<MockedEndpoint[]>;
472
}
473
474
interface RequestRuleData {
475
// Rule data structure for manual rule construction
476
// Complex internal format - use fluent builders when possible
477
}
478
```
479
480
**Usage Examples:**
481
482
```typescript
483
import { getLocal } from "mockttp";
484
485
const mockServer = getLocal();
486
await mockServer.start();
487
488
// Typically you would use the fluent API instead:
489
const endpoint = await mockServer.forGet("/api/test").thenReply(200, "OK");
490
491
// But manual rule management enables advanced scenarios:
492
const rules = [
493
// ... manually constructed RequestRuleData objects
494
];
495
const endpoints = await mockServer.setRequestRules(...rules);
496
```
497
498
### URL Pattern Matching
499
500
Mockttp supports flexible URL matching patterns:
501
502
**Relative Paths**: `/api/users` - matches path only, ignoring host and protocol
503
**Host + Path**: `api.example.com/users` - matches host and path, any protocol
504
**Full URLs**: `https://api.example.com/users` - matches complete URL
505
**Regular Expressions**: `/^\/api\/users\/\d+$/` - flexible pattern matching
506
**Wildcards**: `/api/users/*` - simple wildcard patterns
507
508
Query parameters are always ignored in URL matching. Use `withQuery()` or `withExactQuery()` to match query parameters.
509
510
### Request Matching Priority
511
512
Rules are matched in this order:
513
1. **Method-specific rules** (forGet, forPost, etc.) with DEFAULT priority
514
2. **Generic rules** (forAnyRequest) with DEFAULT priority
515
3. **Method-specific rules** with FALLBACK priority
516
4. **Generic rules** with FALLBACK priority
517
5. **Unmatched request rules** (forUnmatchedRequest)
518
519
Within the same priority level, rules are matched in the order they were added.