or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

certificate-management.mdevent-monitoring.mdhttp-request-mocking.mdindex.mdmock-server-setup.mdresponse-actions.mdwebsocket-mocking.md

response-actions.mddocs/

0

# Response Actions

1

2

Comprehensive response generation system supporting fixed responses, dynamic callbacks, file streaming, request forwarding, and connection manipulation for simulating various server behaviors.

3

4

## Capabilities

5

6

### Fixed Responses

7

8

Simple static responses with predefined status, body, and headers.

9

10

```typescript { .api }

11

interface RequestRuleBuilder {

12

/**

13

* Send a fixed response with specified status code, body, and optional headers/trailers.

14

* Body can be string, Buffer, or object (automatically JSON-serialized).

15

*/

16

thenReply(

17

status: number,

18

data?: string | Buffer | object,

19

headers?: Headers,

20

trailers?: Trailers

21

): Promise<MockedEndpoint>;

22

23

/**

24

* Send a fixed response with specified status code, custom status message, body, and optional headers/trailers.

25

*/

26

thenReply(

27

status: number,

28

statusMessage: string,

29

data: string | Buffer,

30

headers?: Headers,

31

trailers?: Trailers

32

): Promise<MockedEndpoint>;

33

34

/**

35

* Send a JSON response with specified status code and object data.

36

* Automatically sets Content-Type to application/json.

37

*/

38

thenJson(

39

status: number,

40

data: object,

41

headers?: Headers

42

): Promise<MockedEndpoint>;

43

44

/**

45

* Send response from a file with specified status and optional headers.

46

*/

47

thenFromFile(

48

status: number,

49

filePath: string,

50

headers?: Headers

51

): Promise<MockedEndpoint>;

52

53

/**

54

* Send response from a file with specified status, custom status message, and optional headers.

55

*/

56

thenFromFile(

57

status: number,

58

statusMessage: string,

59

filePath: string,

60

headers?: Headers

61

): Promise<MockedEndpoint>;

62

}

63

64

interface Headers {

65

[key: string]: undefined | string | string[];

66

}

67

68

interface Trailers {

69

[key: string]: undefined | string | string[];

70

}

71

```

72

73

**Usage Examples:**

74

75

```typescript

76

import { getLocal } from "mockttp";

77

78

const mockServer = getLocal();

79

await mockServer.start();

80

81

// Simple text response

82

await mockServer.forGet("/api/hello")

83

.thenReply(200, "Hello, World!");

84

85

// JSON response with custom headers

86

await mockServer.forGet("/api/users")

87

.thenJson(200,

88

{ users: [{ id: 1, name: "Alice" }] },

89

{ "X-Total-Count": "1" }

90

);

91

92

// Binary response with Buffer

93

const imageBuffer = Buffer.from("binary-image-data");

94

await mockServer.forGet("/api/avatar.png")

95

.thenReply(200, imageBuffer, {

96

"Content-Type": "image/png",

97

"Cache-Control": "max-age=3600"

98

});

99

100

// Response with trailers (HTTP/1.1 chunked encoding)

101

await mockServer.forGet("/api/stream")

102

.thenReply(200, "Response body",

103

{ "Transfer-Encoding": "chunked" },

104

{ "X-Checksum": "abc123" }

105

);

106

107

// File response

108

await mockServer.forGet("/download/file.pdf")

109

.thenFromFile(200, "/path/to/file.pdf", {

110

"Content-Type": "application/pdf",

111

"Content-Disposition": "attachment; filename=file.pdf"

112

});

113

```

114

115

### Dynamic Responses

116

117

Generate responses dynamically based on request content using callback functions.

118

119

```typescript { .api }

120

interface RequestRuleBuilder {

121

/**

122

* Generate response dynamically using a callback function.

123

* Callback receives the completed request and returns response configuration.

124

*/

125

thenCallback(

126

callback: (request: CompletedRequest) => CallbackResponseResult | Promise<CallbackResponseResult>

127

): Promise<MockedEndpoint>;

128

}

129

130

interface CallbackResponseResult {

131

statusCode?: number;

132

statusMessage?: string;

133

headers?: Headers;

134

trailers?: Trailers;

135

body?: string | Buffer | Uint8Array | object;

136

json?: object;

137

}

138

139

interface CompletedRequest {

140

id: string;

141

matchedRuleId?: string;

142

protocol: string;

143

httpVersion: string;

144

method: string;

145

url: string;

146

path: string;

147

headers: Headers;

148

body: CompletedBody;

149

timingEvents: TimingEvents;

150

tags: string[];

151

}

152

153

interface CompletedBody {

154

buffer: Buffer;

155

getDecodedBuffer(): Promise<Buffer | undefined>;

156

getText(): Promise<string | undefined>;

157

getJson(): Promise<object | undefined>;

158

getFormData(): Promise<{[key: string]: string | string[] | undefined} | undefined>;

159

}

160

```

161

162

**Usage Examples:**

163

164

```typescript

165

import { getLocal } from "mockttp";

166

167

const mockServer = getLocal();

168

await mockServer.start();

169

170

// Echo request data back

171

await mockServer.forPost("/api/echo")

172

.thenCallback(async (request) => {

173

const body = await request.body.getText();

174

return {

175

statusCode: 200,

176

headers: { "Content-Type": "text/plain" },

177

body: `Echo: ${body}`

178

};

179

});

180

181

// Dynamic JSON response based on request

182

await mockServer.forGet("/api/user/*")

183

.thenCallback(async (request) => {

184

const userId = request.path.split('/').pop();

185

const userAgent = request.headers['user-agent'] || 'unknown';

186

187

return {

188

json: {

189

id: userId,

190

userAgent: userAgent,

191

timestamp: new Date().toISOString()

192

}

193

};

194

});

195

196

// Conditional response based on headers

197

await mockServer.forPost("/api/auth")

198

.thenCallback(async (request) => {

199

const authHeader = request.headers.authorization;

200

201

if (authHeader === 'Bearer valid-token') {

202

return { statusCode: 200, json: { authenticated: true } };

203

} else {

204

return {

205

statusCode: 401,

206

json: { error: "Invalid token" },

207

headers: { "WWW-Authenticate": "Bearer" }

208

};

209

}

210

});

211

212

// Process form data

213

await mockServer.forPost("/api/contact")

214

.thenCallback(async (request) => {

215

const formData = await request.body.getFormData();

216

const email = formData?.email;

217

218

if (email && typeof email === 'string') {

219

return {

220

statusCode: 200,

221

json: { message: `Thank you, ${email}!` }

222

};

223

} else {

224

return {

225

statusCode: 400,

226

json: { error: "Email required" }

227

};

228

}

229

});

230

```

231

232

### Stream Responses

233

234

Send responses from readable streams for large files or real-time data.

235

236

```typescript { .api }

237

interface RequestRuleBuilder {

238

/**

239

* Send response from a readable stream.

240

* Useful for large files or streaming data.

241

*/

242

thenStream(

243

status: number,

244

stream: stream.Readable,

245

headers?: Headers

246

): Promise<MockedEndpoint>;

247

}

248

```

249

250

**Usage Examples:**

251

252

```typescript

253

import { getLocal } from "mockttp";

254

import * as fs from "fs";

255

import { Readable } from "stream";

256

257

const mockServer = getLocal();

258

await mockServer.start();

259

260

// Stream file response

261

await mockServer.forGet("/api/large-file")

262

.thenStream(200,

263

fs.createReadStream("/path/to/large-file.json"),

264

{ "Content-Type": "application/json" }

265

);

266

267

// Stream generated data

268

await mockServer.forGet("/api/live-data")

269

.thenStream(200,

270

Readable.from(generateDataStream()),

271

{

272

"Content-Type": "text/plain",

273

"Transfer-Encoding": "chunked"

274

}

275

);

276

277

async function* generateDataStream() {

278

for (let i = 0; i < 1000; i++) {

279

yield `Data chunk ${i}\n`;

280

await new Promise(resolve => setTimeout(resolve, 10));

281

}

282

}

283

```

284

285

### Request Forwarding

286

287

Forward requests to real servers with optional transformations.

288

289

```typescript { .api }

290

interface RequestRuleBuilder {

291

/**

292

* Forward request to the original target server.

293

* Useful for selective mocking while allowing real traffic through.

294

*/

295

thenPassThrough(options?: PassThroughStepOptions): Promise<MockedEndpoint>;

296

297

/**

298

* Forward request to a specific target URL.

299

* Enables request proxying and redirection.

300

*/

301

thenForwardTo(

302

target: string,

303

options?: PassThroughStepOptions

304

): Promise<MockedEndpoint>;

305

}

306

307

interface PassThroughStepOptions {

308

/**

309

* Transformations to apply to outgoing request.

310

*/

311

transformRequest?: RequestTransform;

312

313

/**

314

* Transformations to apply to incoming response.

315

*/

316

transformResponse?: ResponseTransform;

317

318

/**

319

* Custom DNS lookup function for request destination.

320

*/

321

lookupOptions?: PassThroughLookupOptions;

322

323

/**

324

* Connection options for upstream request.

325

*/

326

connectionOptions?: PassThroughStepConnectionOptions;

327

328

/**

329

* Initial transforms before forwarding.

330

*/

331

initialTransforms?: PassThroughInitialTransforms;

332

333

/**

334

* Forwarding configuration options.

335

*/

336

forwardingOptions?: ForwardingOptions;

337

}

338

339

interface RequestTransform {

340

updateHeaders?: (headers: Headers) => Headers;

341

updateBody?: (body: Buffer) => Buffer | Promise<Buffer>;

342

}

343

344

interface ResponseTransform {

345

updateStatus?: (status: number) => number;

346

updateHeaders?: (headers: Headers) => Headers;

347

updateBody?: (body: Buffer) => Buffer | Promise<Buffer>;

348

}

349

```

350

351

**Usage Examples:**

352

353

```typescript

354

import { getLocal } from "mockttp";

355

356

const mockServer = getLocal();

357

await mockServer.start();

358

359

// Pass through to original server

360

await mockServer.forGet("/api/external")

361

.thenPassThrough();

362

363

// Forward to different server

364

await mockServer.forPost("/api/proxy")

365

.thenForwardTo("https://api.example.com/v1/data");

366

367

// Forward with request transformation

368

await mockServer.forPost("/api/transform")

369

.thenForwardTo("https://api.example.com/webhook", {

370

transformRequest: {

371

updateHeaders: (headers) => ({

372

...headers,

373

'X-Forwarded-By': 'mockttp',

374

'Authorization': 'Bearer secret-token'

375

})

376

}

377

});

378

379

// Forward with response transformation

380

await mockServer.forGet("/api/filtered")

381

.thenPassThrough({

382

transformResponse: {

383

updateStatus: (status) => status === 404 ? 200 : status,

384

updateBody: async (body) => {

385

const data = JSON.parse(body.toString());

386

return Buffer.from(JSON.stringify({

387

...data,

388

filtered: true,

389

timestamp: Date.now()

390

}));

391

}

392

}

393

});

394

```

395

396

### Connection Control

397

398

Control connection behavior for testing network conditions and error scenarios.

399

400

```typescript { .api }

401

interface RequestRuleBuilder {

402

/**

403

* Close the connection immediately without sending a response.

404

* Simulates server crashes or network failures.

405

*/

406

thenCloseConnection(): Promise<MockedEndpoint>;

407

408

/**

409

* Reset the connection with a TCP RST packet.

410

* Simulates aggressive connection termination.

411

*/

412

thenResetConnection(): Promise<MockedEndpoint>;

413

414

/**

415

* Hold the connection open indefinitely without responding.

416

* Simulates server timeouts and hanging connections.

417

*/

418

thenTimeout(): Promise<MockedEndpoint>;

419

}

420

```

421

422

**Usage Examples:**

423

424

```typescript

425

import { getLocal } from "mockttp";

426

427

const mockServer = getLocal();

428

await mockServer.start();

429

430

// Simulate server crash

431

await mockServer.forPost("/api/unreliable")

432

.thenCloseConnection();

433

434

// Simulate connection reset

435

await mockServer.forGet("/api/forbidden")

436

.thenResetConnection();

437

438

// Simulate slow/hanging server

439

await mockServer.forGet("/api/slow")

440

.thenTimeout();

441

442

// Combined with execution control for flaky behavior

443

await mockServer.forPost("/api/flaky")

444

.twice()

445

.thenCloseConnection();

446

447

// Then add a fallback rule

448

await mockServer.forPost("/api/flaky")

449

.thenReply(200, { success: true });

450

```

451

452

### Response Timing

453

454

Add delays to simulate network latency and slow servers.

455

456

```typescript { .api }

457

interface RequestRuleBuilder {

458

/**

459

* Add a delay before processing the next step.

460

* Can be chained with other response actions.

461

*/

462

delay(ms: number): this;

463

}

464

```

465

466

**Usage Examples:**

467

468

```typescript

469

import { getLocal } from "mockttp";

470

471

const mockServer = getLocal();

472

await mockServer.start();

473

474

// Slow response simulation

475

await mockServer.forGet("/api/slow")

476

.delay(2000) // 2 second delay

477

.thenReply(200, { data: "finally!" });

478

479

// Variable delay with callback

480

await mockServer.forGet("/api/variable")

481

.delay(Math.random() * 1000) // 0-1 second random delay

482

.thenJson(200, { timestamp: Date.now() });

483

484

// Delayed forwarding

485

await mockServer.forPost("/api/slow-proxy")

486

.delay(500)

487

.thenForwardTo("https://slow-api.example.com/endpoint");

488

```

489

490

### JSON-RPC Responses

491

492

Specialized responses for JSON-RPC protocol support.

493

494

```typescript { .api }

495

interface RequestRuleBuilder {

496

/**

497

* Send a JSON-RPC success response with the given result.

498

* Automatically formats with jsonrpc: "2.0" and proper structure.

499

*/

500

thenSendJsonRpcResult(

501

result: any,

502

id?: string | number

503

): Promise<MockedEndpoint>;

504

505

/**

506

* Send a JSON-RPC error response with the given error details.

507

* Automatically formats with jsonrpc: "2.0" and proper error structure.

508

*/

509

thenSendJsonRpcError(

510

error: {code: number, message: string, data?: any},

511

id?: string | number

512

): Promise<MockedEndpoint>;

513

}

514

```

515

516

**Usage Examples:**

517

518

```typescript

519

import { getLocal } from "mockttp";

520

521

const mockServer = getLocal();

522

await mockServer.start();

523

524

// JSON-RPC success response

525

await mockServer.forJsonRpcRequest({ method: "getUser" })

526

.thenSendJsonRpcResult({

527

id: 123,

528

name: "Alice",

529

email: "alice@example.com"

530

});

531

532

// JSON-RPC error response

533

await mockServer.forJsonRpcRequest({ method: "deleteUser" })

534

.thenSendJsonRpcError({

535

code: -32602,

536

message: "Invalid params",

537

data: { required: ["id"] }

538

});

539

540

// Dynamic JSON-RPC with callback

541

await mockServer.forJsonRpcRequest()

542

.thenCallback(async (request) => {

543

const body = await request.body.getJson() as any;

544

545

if (body.method === "add") {

546

const [a, b] = body.params;

547

return {

548

json: {

549

jsonrpc: "2.0",

550

result: a + b,

551

id: body.id

552

}

553

};

554

} else {

555

return {

556

json: {

557

jsonrpc: "2.0",

558

error: {

559

code: -32601,

560

message: "Method not found"

561

},

562

id: body.id

563

}

564

};

565

}

566

});

567

```

568

569

### Response Chaining

570

571

Multiple response actions can be chained for complex scenarios:

572

573

```typescript

574

import { getLocal } from "mockttp";

575

576

const mockServer = getLocal();

577

await mockServer.start();

578

579

// Delayed response with custom headers

580

await mockServer.forGet("/api/complex")

581

.delay(1000)

582

.thenReply(200, "Success", {

583

"X-Processing-Time": "1000",

584

"X-Server": "mockttp"

585

});

586

```

587

588

All response methods return `Promise<MockedEndpoint>` which provides access to the created rule for monitoring and testing.