or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdinterceptors.mdmime-system.mdurl-building.md

interceptors.mddocs/

0

# Interceptors

1

2

Interceptors provide a composable middleware pattern for extending rest.js client functionality. They can transform requests, responses, or both, allowing you to add features like authentication, error handling, caching, and content negotiation.

3

4

## Capabilities

5

6

### Base Interceptor System

7

8

Core interceptor creation and composition functionality.

9

10

```javascript { .api }

11

const interceptor = require('rest/interceptor');

12

13

/**

14

* Create a custom interceptor

15

* @param {object} handlers - Interceptor handler functions

16

* @param {function} [handlers.init] - One-time initialization

17

* @param {function} [handlers.request] - Request transformation

18

* @param {function} [handlers.response] - Response transformation

19

* @param {function} [handlers.success] - Success response handler

20

* @param {function} [handlers.error] - Error response handler

21

* @param {Client} [handlers.client] - Default client to use

22

* @returns {Interceptor} Interceptor function

23

*/

24

function interceptor(handlers)

25

26

/**

27

* Complex request object for advanced interceptor scenarios

28

* @param {object} properties - Request properties

29

* @param {Request} properties.request - The request object

30

* @param {Promise} [properties.abort] - Abort promise

31

* @param {Client} [properties.client] - Override client

32

* @param {any} [properties.response] - Short-circuit response

33

*/

34

function ComplexRequest(properties)

35

```

36

37

**Usage Example:**

38

39

```javascript

40

const interceptor = require('rest/interceptor');

41

42

const customInterceptor = interceptor({

43

request: function(request, config, meta) {

44

// Transform request

45

request.headers = request.headers || {};

46

request.headers['X-Custom-Header'] = 'my-value';

47

return request;

48

},

49

response: function(response, config, meta) {

50

// Transform response

51

console.log('Response received:', response.status.code);

52

return response;

53

}

54

});

55

56

const client = rest.wrap(customInterceptor);

57

```

58

59

### Authentication Interceptors

60

61

#### Basic Authentication

62

63

HTTP Basic Authentication support.

64

65

```javascript { .api }

66

const basicAuth = require('rest/interceptor/basicAuth');

67

68

/**

69

* Basic Auth interceptor configuration

70

* @param {object} config - Authentication config

71

* @param {string} config.username - Username

72

* @param {string} config.password - Password

73

*/

74

```

75

76

**Usage Example:**

77

78

```javascript

79

const basicAuth = require('rest/interceptor/basicAuth');

80

81

const client = rest.wrap(basicAuth, {

82

username: 'myuser',

83

password: 'mypassword'

84

});

85

```

86

87

#### OAuth Support

88

89

OAuth authentication interceptor.

90

91

```javascript { .api }

92

const oAuth = require('rest/interceptor/oAuth');

93

94

/**

95

* OAuth interceptor for request signing

96

*/

97

```

98

99

### Request/Response Transformation

100

101

#### MIME Type Conversion

102

103

Automatic serialization/deserialization based on Content-Type.

104

105

```javascript { .api }

106

const mime = require('rest/interceptor/mime');

107

108

/**

109

* MIME interceptor configuration

110

* @param {object} config - MIME config

111

* @param {string} [config.mime='text/plain'] - Default request MIME type

112

* @param {string} [config.accept] - Accept header value

113

* @param {Registry} [config.registry] - Custom MIME registry

114

* @param {boolean} [config.permissive=false] - Allow unknown MIME types

115

* @param {Client} [config.client] - Client for converter use

116

*/

117

```

118

119

#### Entity Interceptor (Deprecated)

120

121

Extract response entity directly.

122

123

```javascript { .api }

124

const entity = require('rest/interceptor/entity');

125

126

// Note: This interceptor is deprecated. Use response.entity() instead.

127

```

128

129

### Error Handling

130

131

#### Error Code Interceptor

132

133

Reject responses based on HTTP status codes.

134

135

```javascript { .api }

136

const errorCode = require('rest/interceptor/errorCode');

137

138

/**

139

* Error code interceptor configuration

140

* @param {object} config - Error config

141

* @param {number} [config.code=400] - Minimum error status code

142

*/

143

```

144

145

**Usage Example:**

146

147

```javascript

148

const errorCode = require('rest/interceptor/errorCode');

149

150

const client = rest.wrap(errorCode, { code: 500 });

151

// Only reject on 500+ status codes

152

```

153

154

#### Retry Interceptor

155

156

Automatically retry failed requests.

157

158

```javascript { .api }

159

const retry = require('rest/interceptor/retry');

160

161

/**

162

* Retry interceptor for handling transient failures

163

*/

164

```

165

166

#### Timeout Interceptor

167

168

Add request timeout handling.

169

170

```javascript { .api }

171

const timeout = require('rest/interceptor/timeout');

172

173

/**

174

* Timeout interceptor configuration

175

* @param {object} config - Timeout config

176

* @param {number} config.timeout - Timeout in milliseconds

177

*/

178

```

179

180

### URL and Path Manipulation

181

182

#### Path Prefix Interceptor

183

184

Add a prefix to all request paths.

185

186

```javascript { .api }

187

const pathPrefix = require('rest/interceptor/pathPrefix');

188

189

/**

190

* Path prefix interceptor configuration

191

* @param {object} config - Prefix config

192

* @param {string} config.prefix - Path prefix to add

193

*/

194

```

195

196

**Usage Example:**

197

198

```javascript

199

const pathPrefix = require('rest/interceptor/pathPrefix');

200

201

const client = rest.wrap(pathPrefix, { prefix: '/api/v1' });

202

// Requests to '/users' become '/api/v1/users'

203

```

204

205

#### Template Interceptor

206

207

URI template expansion using RFC 6570.

208

209

```javascript { .api }

210

const template = require('rest/interceptor/template');

211

212

/**

213

* URI template interceptor for parameter expansion

214

*/

215

```

216

217

#### Parameters Interceptor (Deprecated)

218

219

Simple parameter replacement in URLs.

220

221

```javascript { .api }

222

const params = require('rest/interceptor/params');

223

224

// Note: This interceptor is deprecated. Use template interceptor instead.

225

```

226

227

### Request Configuration

228

229

#### Default Request Interceptor

230

231

Provide default values for request properties.

232

233

```javascript { .api }

234

const defaultRequest = require('rest/interceptor/defaultRequest');

235

236

/**

237

* Default request interceptor configuration

238

* @param {object} config - Default request properties

239

*/

240

```

241

242

**Usage Example:**

243

244

```javascript

245

const defaultRequest = require('rest/interceptor/defaultRequest');

246

247

const client = rest.wrap(defaultRequest, {

248

headers: { 'User-Agent': 'MyApp/1.0' },

249

method: 'POST'

250

});

251

```

252

253

### Hypermedia and Location Handling

254

255

#### HATEOAS Interceptor

256

257

Hypermedia support for following links and parsing Link headers according to RFC 5988.

258

259

```javascript { .api }

260

const hateoas = require('rest/interceptor/hateoas');

261

262

/**

263

* HATEOAS interceptor configuration

264

* @param {object} config - HATEOAS config

265

* @param {string} [config.target=''] - Property to create on entity for links

266

* @param {Client} [config.client] - Client to use for following links

267

*/

268

```

269

270

**Usage Example:**

271

272

```javascript

273

const hateoas = require('rest/interceptor/hateoas');

274

275

const client = rest.wrap(hateoas);

276

277

client('/api/users/123').then(function(response) {

278

// Links are now accessible on the entity

279

if (response.entity.next) {

280

// Follow the 'next' relationship

281

return response.entity.next();

282

}

283

284

// Access link objects directly

285

console.log(response.entity.nextLink); // Link object reference

286

});

287

```

288

289

#### Location Interceptor

290

291

Follow Location response headers.

292

293

```javascript { .api }

294

const location = require('rest/interceptor/location');

295

296

/**

297

* Location interceptor configuration

298

* @param {object} config - Location config

299

* @param {number|function} [config.code] - Status codes to follow

300

*/

301

```

302

303

### Cross-Origin and Security

304

305

#### JSONP Interceptor

306

307

JSONP support for cross-origin requests.

308

309

```javascript { .api }

310

const jsonp = require('rest/interceptor/jsonp');

311

312

/**

313

* JSONP interceptor for cross-origin requests

314

* @param {object} config - JSONP config

315

* @param {string} [config.callback] - Callback parameter name

316

*/

317

```

318

319

#### CSRF Protection

320

321

Cross-Site Request Forgery protection.

322

323

```javascript { .api }

324

const csrf = require('rest/interceptor/csrf');

325

326

/**

327

* CSRF protection interceptor

328

*/

329

```

330

331

## Interceptor Composition

332

333

Interceptors can be chained together to create complex client behaviors:

334

335

```javascript

336

const mime = require('rest/interceptor/mime');

337

const basicAuth = require('rest/interceptor/basicAuth');

338

const errorCode = require('rest/interceptor/errorCode');

339

const pathPrefix = require('rest/interceptor/pathPrefix');

340

341

const client = rest

342

.wrap(pathPrefix, { prefix: '/api/v1' })

343

.wrap(basicAuth, { username: 'user', password: 'pass' })

344

.wrap(mime)

345

.wrap(errorCode, { code: 400 });

346

347

// This client will:

348

// 1. Add '/api/v1' prefix to all paths

349

// 2. Add Basic Auth headers

350

// 3. Handle MIME type conversion

351

// 4. Reject responses with status >= 400

352

```

353

354

## Custom Interceptor Development

355

356

Create custom interceptors for specialized functionality:

357

358

```javascript

359

const interceptor = require('rest/interceptor');

360

361

const loggingInterceptor = interceptor({

362

init: function(config) {

363

config.logLevel = config.logLevel || 'info';

364

return config;

365

},

366

request: function(request, config) {

367

console.log(`[${config.logLevel}] Request:`, request.method, request.path);

368

return request;

369

},

370

response: function(response, config) {

371

console.log(`[${config.logLevel}] Response:`, response.status.code);

372

return response;

373

},

374

error: function(response, config) {

375

console.error(`[${config.logLevel}] Error:`, response.status.code);

376

// Return rejected promise to maintain error state

377

return Promise.reject(response);

378

}

379

});

380

381

const client = rest.wrap(loggingInterceptor, { logLevel: 'debug' });

382

```