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
```