npm-express

Description
Fast, unopinionated, minimalist web framework for Node.js
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/npm-express@4.21.0

request.md docs/

1
# Request Processing
2
3
Enhanced request object with Express-specific properties and methods for handling incoming HTTP requests, accessing headers, parameters, and parsing request data.
4
5
## Capabilities
6
7
### Request Properties
8
9
Access request information including URL components, headers, and parsed data.
10
11
```javascript { .api }
12
/**
13
* Express request object extends Node.js IncomingMessage
14
*/
15
interface Request {
16
/** Reference to Express application instance */
17
app: Application;
18
/** Base URL path (mount path for sub-apps) */
19
baseUrl: string;
20
/** Request body (populated by body parsing middleware) */
21
body: any;
22
/** Parsed cookies from Cookie header */
23
cookies: { [key: string]: string };
24
/** Signed cookies when cookie-parser used with secret */
25
signedCookies: { [key: string]: string };
26
/** Check if request is fresh (based on Last-Modified/ETag) */
27
fresh: boolean;
28
/** Request hostname (Host header without port) */
29
hostname: string;
30
/** Remote IP address */
31
ip: string;
32
/** Array of IP addresses (when trust proxy enabled) */
33
ips: string[];
34
/** HTTP method (GET, POST, etc.) */
35
method: string;
36
/** Original URL as received by the server */
37
originalUrl: string;
38
/** Route parameters from URL path */
39
params: { [key: string]: string };
40
/** Request path portion of URL */
41
path: string;
42
/** Request protocol (http or https) */
43
protocol: string;
44
/** Parsed query string parameters */
45
query: { [key: string]: any };
46
/** Raw query string */
47
rawQuery: string;
48
/** Currently matched route object */
49
route: Route;
50
/** True if connection is secure (HTTPS) */
51
secure: boolean;
52
/** True if request is stale (opposite of fresh) */
53
stale: boolean;
54
/** Array of subdomains */
55
subdomains: string[];
56
/** True if request is XMLHttpRequest (Ajax) */
57
xhr: boolean;
58
}
59
```
60
61
**Usage Examples:**
62
63
```javascript
64
app.get('/info', (req, res) => {
65
const requestInfo = {
66
method: req.method, // 'GET'
67
path: req.path, // '/info'
68
hostname: req.hostname, // 'localhost'
69
protocol: req.protocol, // 'http'
70
secure: req.secure, // false
71
ip: req.ip, // '127.0.0.1'
72
xhr: req.xhr, // false
73
fresh: req.fresh, // true/false
74
stale: req.stale // true/false
75
};
76
77
res.json(requestInfo);
78
});
79
80
// Access route parameters
81
app.get('/users/:id/posts/:postId', (req, res) => {
82
const { id, postId } = req.params;
83
res.json({ userId: id, postId });
84
});
85
86
// Access query parameters
87
app.get('/search', (req, res) => {
88
const { q, limit, offset } = req.query;
89
res.json({ query: q, limit, offset });
90
});
91
92
// Access request body (requires body parser)
93
app.post('/users', (req, res) => {
94
const { name, email } = req.body;
95
res.json({ name, email });
96
});
97
```
98
99
### Header Access
100
101
Retrieve request headers and perform content negotiation.
102
103
```javascript { .api }
104
/**
105
* Get request header value (case-insensitive)
106
* @param {string} field - Header field name
107
* @returns {string | undefined} Header value or undefined
108
*/
109
req.get(field: string): string | undefined;
110
111
/**
112
* Alias for req.get()
113
* @param {string} field - Header field name
114
* @returns {string | undefined} Header value or undefined
115
*/
116
req.header(field: string): string | undefined;
117
```
118
119
**Usage Examples:**
120
121
```javascript
122
app.get('/headers', (req, res) => {
123
const headers = {
124
userAgent: req.get('User-Agent'),
125
contentType: req.get('Content-Type'),
126
authorization: req.header('authorization'),
127
accept: req.get('Accept'),
128
host: req.get('Host')
129
};
130
131
res.json(headers);
132
});
133
134
// Custom header processing
135
app.use((req, res, next) => {
136
const apiKey = req.get('X-API-Key');
137
const version = req.get('X-API-Version') || 'v1';
138
139
req.apiKey = apiKey;
140
req.apiVersion = version;
141
next();
142
});
143
```
144
145
### Content Negotiation
146
147
Determine client preferences for response format based on Accept headers.
148
149
```javascript { .api }
150
/**
151
* Check if request accepts specified content types
152
* @param {string | string[]} types - MIME types to check
153
* @returns {string | false} Best matching type or false
154
*/
155
req.accepts(types?: string | string[]): string | false;
156
157
/**
158
* Check if request accepts specified charsets
159
* @param {string | string[]} charsets - Character sets to check
160
* @returns {string | false} Best matching charset or false
161
*/
162
req.acceptsCharsets(charsets?: string | string[]): string | false;
163
164
/**
165
* Check if request accepts specified encodings
166
* @param {string | string[]} encodings - Content encodings to check
167
* @returns {string | false} Best matching encoding or false
168
*/
169
req.acceptsEncodings(encodings?: string | string[]): string | false;
170
171
/**
172
* Check if request accepts specified languages
173
* @param {string | string[]} languages - Languages to check
174
* @returns {string | false} Best matching language or false
175
*/
176
req.acceptsLanguages(languages?: string | string[]): string | false;
177
```
178
179
**Usage Examples:**
180
181
```javascript
182
app.get('/data', (req, res) => {
183
const accepts = req.accepts(['json', 'xml', 'html']);
184
185
switch (accepts) {
186
case 'json':
187
res.json({ message: 'JSON response' });
188
break;
189
case 'xml':
190
res.type('xml').send('<message>XML response</message>');
191
break;
192
case 'html':
193
res.send('<h1>HTML response</h1>');
194
break;
195
default:
196
res.status(406).send('Not Acceptable');
197
}
198
});
199
200
// Language negotiation
201
app.get('/greeting', (req, res) => {
202
const lang = req.acceptsLanguages(['en', 'es', 'fr']);
203
204
const greetings = {
205
en: 'Hello',
206
es: 'Hola',
207
fr: 'Bonjour'
208
};
209
210
res.json({
211
greeting: greetings[lang] || greetings.en,
212
language: lang || 'en'
213
});
214
});
215
216
// Encoding negotiation
217
app.get('/large-data', (req, res) => {
218
const encoding = req.acceptsEncodings(['gzip', 'deflate']);
219
220
if (encoding) {
221
// Compress response based on accepted encoding
222
res.set('Content-Encoding', encoding);
223
}
224
225
res.json({ data: 'large dataset', compressed: !!encoding });
226
});
227
```
228
229
### Content Type Checking
230
231
Check the content type of incoming requests.
232
233
```javascript { .api }
234
/**
235
* Check if request content type matches specified types
236
* @param {string | string[]} types - Content types to check against
237
* @returns {string | false} Matching type or false
238
*/
239
req.is(types: string | string[]): string | false;
240
```
241
242
**Usage Examples:**
243
244
```javascript
245
app.post('/upload', (req, res) => {
246
if (req.is('application/json')) {
247
// Handle JSON upload
248
res.json({ type: 'json', body: req.body });
249
} else if (req.is('multipart/form-data')) {
250
// Handle file upload
251
res.json({ type: 'multipart' });
252
} else if (req.is('text/*')) {
253
// Handle any text content
254
res.json({ type: 'text' });
255
} else {
256
res.status(415).json({ error: 'Unsupported Media Type' });
257
}
258
});
259
260
// Multiple content type check
261
app.post('/api/data', (req, res) => {
262
const contentType = req.is(['json', 'urlencoded', 'text']);
263
264
if (!contentType) {
265
return res.status(415).json({
266
error: 'Content-Type must be JSON, form data, or text'
267
});
268
}
269
270
res.json({ acceptedType: contentType });
271
});
272
```
273
274
### Range Header Processing
275
276
Handle Range requests for partial content (useful for file serving and streaming).
277
278
```javascript { .api }
279
/**
280
* Parse Range header for partial content requests
281
* @param {number} size - Total size of the resource
282
* @param {RangeOptions} [options] - Range parsing options
283
* @returns {RangeResult | undefined} Parsed range or undefined
284
*/
285
req.range(size: number, options?: RangeOptions): RangeResult | undefined;
286
287
/**
288
* Range parsing options
289
*/
290
interface RangeOptions {
291
/** Combine overlapping ranges (default: false) */
292
combine?: boolean;
293
}
294
295
/**
296
* Range parsing result
297
*/
298
interface RangeResult {
299
/** Range type (usually 'bytes') */
300
type: string;
301
/** Array of range specifications */
302
ranges: Array<{
303
start: number;
304
end: number;
305
}>;
306
}
307
```
308
309
**Usage Examples:**
310
311
```javascript
312
const fs = require('fs');
313
314
app.get('/video/:id', (req, res) => {
315
const videoPath = `./videos/${req.params.id}.mp4`;
316
const stat = fs.statSync(videoPath);
317
const fileSize = stat.size;
318
319
const range = req.range(fileSize);
320
321
if (range) {
322
// Handle range request for video streaming
323
const { start, end } = range.ranges[0];
324
const chunkSize = (end - start) + 1;
325
const stream = fs.createReadStream(videoPath, { start, end });
326
327
res.status(206); // Partial Content
328
res.set({
329
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
330
'Accept-Ranges': 'bytes',
331
'Content-Length': chunkSize,
332
'Content-Type': 'video/mp4'
333
});
334
335
stream.pipe(res);
336
} else {
337
// Send entire file
338
res.set({
339
'Content-Length': fileSize,
340
'Content-Type': 'video/mp4'
341
});
342
fs.createReadStream(videoPath).pipe(res);
343
}
344
});
345
```
346
347
### Parameter Access (Deprecated)
348
349
Legacy parameter access method (deprecated in favor of specific property access).
350
351
```javascript { .api }
352
/**
353
* Get parameter value from params, body, or query (deprecated)
354
* @param {string} name - Parameter name
355
* @param {any} [defaultValue] - Default value if not found
356
* @returns {any} Parameter value or default
357
* @deprecated Use req.params, req.body, or req.query directly
358
*/
359
req.param(name: string, defaultValue?: any): any;
360
```
361
362
**Usage Examples (Not Recommended):**
363
364
```javascript
365
// Deprecated - don't use
366
app.get('/old-style/:id', (req, res) => {
367
const id = req.param('id'); // Gets from params
368
const name = req.param('name'); // Gets from query/body
369
370
res.json({ id, name });
371
});
372
373
// Preferred modern approach
374
app.get('/modern/:id', (req, res) => {
375
const { id } = req.params;
376
const { name } = req.query;
377
378
res.json({ id, name });
379
});
380
```
381
382
## Request Object Extensions
383
384
Custom properties can be added to the request object by middleware for sharing data between middleware functions.
385
386
```javascript
387
// Type extension for custom properties
388
declare global {
389
namespace Express {
390
interface Request {
391
user?: User;
392
apiKey?: string;
393
apiVersion?: string;
394
requestId?: string;
395
}
396
}
397
}
398
399
// Middleware adding custom properties
400
app.use((req, res, next) => {
401
req.requestId = generateRequestId();
402
next();
403
});
404
405
app.use('/api', (req, res, next) => {
406
req.apiVersion = req.get('X-API-Version') || 'v1';
407
next();
408
});
409
```