diff --git a/src/content/api/4x/api/express/index.mdx b/src/content/api/4x/api/express/index.mdx index 540a0ed176..b4f5d0a794 100644 --- a/src/content/api/4x/api/express/index.mdx +++ b/src/content/api/4x/api/express/index.mdx @@ -47,10 +47,26 @@ const app: Express = express(); The `reviver` option is passed directly to `JSON.parse` as the second argument. You can find more information on this argument [in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#the_reviver_parameter). + + ```js + app.use(express.json({ + reviver: (key, value) => key === 'createdAt' ? new Date(value) : value, + })); + // Body: {"createdAt":"2026-01-01T00:00:00Z"} + // req.body.createdAt is a Date. + ``` + Enables or disables only accepting arrays and objects; when disabled will accept anything `JSON.parse` accepts. + + ```js + app.use(express.json({ strict: false })); + // Body: 42 -> req.body is the number 42. + // With strict: true (the default), this body is rejected with status 400. + ``` + This is used to determine what media type the middleware will parse. This option can be a @@ -64,6 +80,16 @@ const app: Express = express(); This option, if supplied, is called as `verify(req, res, buf, encoding)`, where `buf` is a `Buffer` of the raw request body and `encoding` is the encoding of the request. The parsing can be aborted by throwing an error. + + ```js + app.use(express.json({ + verify: (req, res, buf) => { + req.rawBody = buf; + }, + })); + // req.rawBody contains the original Buffer, before JSON parsing. + ``` + @@ -241,15 +267,43 @@ app.post('/upload', (req: Request, res: Response) => { Enable case sensitivity. Disabled by default, treating `/Foo` and `/foo` as the same. + + ```js + // caseSensitive: treat "/Foo" and "/foo" as different routes + const router = express.Router({ caseSensitive: true }); + router.get('/Foo', (req, res) => res.send('Matched /Foo exactly')); + ``` + Preserve the `req.params` values from the parent router. If the parent and the child have conflicting param names, the child's value take precedence. + + ```js + // mergeParams: access parent route params in child router + const parent = express.Router(); + const child = express.Router({ mergeParams: true }); + + parent.use('/user/:userId', child); + child.get('/comments', (req, res) => { + // req.params.userId is available because mergeParams: true + res.send(`Comments for user ${req.params.userId}`); + }); + ``` + Enable strict routing. Disabled by default, `/foo` and `/foo/` are treated the same by the router. + + ```js + // strict: treat "/foo" and "/foo/" as different routes + const strictRouter = express.Router({ strict: true }); + strictRouter.get('/foo/', (req, res) => res.send('Matched /foo/ with trailing slash')); + ``` + + @@ -296,12 +350,32 @@ For more information, see [Router](/api/router/). Let client errors fall-through as unhandled requests, otherwise forward a client error. See [fallthrough](#fallthrough) below. + + ```js + app.use('/assets', express.static('public', { fallthrough: true })); + app.use('/assets', (req, res) => { + res.status(404).send('Asset not found'); + }); + // Missing files reach the fallback above. + // With fallthrough: false, they reach error-handling middleware instead. + ``` + Enable or disable the `immutable` directive in the `Cache-Control` response header. If enabled, the `maxAge` option should also be specified to enable caching. The `immutable` directive will prevent supported clients from making conditional requests during the life of the `maxAge` option to check if the file has changed. + + ```js + // Use filenames that change whenever the file contents change. + app.use('/assets', express.static('public', { + maxAge: '1y', + immutable: true, + })); + // Cache-Control: public, max-age=31536000, immutable + ``` + Sends the specified directory index file. Set to `false` to disable directory indexing. @@ -572,6 +646,18 @@ app.post('/', (req: Request, res: Response) => { rich objects and arrays to be encoded into the URL-encoded format, allowing for a JSON-like experience with URL-encoded. For more information, please [see the qs library](https://www.npmjs.com/package/qs#readme). + + ```js + // Form body: user[name]=Tobi + app.post('/simple', express.urlencoded({ extended: false }), (req, res) => { + res.json(req.body); // => { 'user[name]': 'Tobi' } + }); + + app.post('/extended', express.urlencoded({ extended: true }), (req, res) => { + res.json(req.body); // => { user: { name: 'Tobi' } } + }); + ``` + Enables or disables handling deflated (compressed) bodies; when disabled, deflated bodies diff --git a/src/content/api/4x/api/request/index.mdx b/src/content/api/4x/api/request/index.mdx index ebd3ba575e..3194ce4450 100644 --- a/src/content/api/4x/api/request/index.mdx +++ b/src/content/api/4x/api/request/index.mdx @@ -983,6 +983,17 @@ Body-parsing middleware must be loaded for `req.param()` to work predictably. Re Specify if overlapping and adjacent ranges should be combined. When `true`, ranges are combined and returned as if they were specified that way in the header. + + ```js + // Range: bytes=0-99,50-149 + const separate = req.range(1000, { combine: false }); + console.log(separate[0]); // => { start: 0, end: 99 } + console.log(separate[1]); // => { start: 50, end: 149 } + + const combined = req.range(1000, { combine: true }); + console.log(combined[0]); // => { start: 0, end: 149 } + ``` + diff --git a/src/content/api/5x/api/express/index.mdx b/src/content/api/5x/api/express/index.mdx index eb191f96fd..df72335acf 100644 --- a/src/content/api/5x/api/express/index.mdx +++ b/src/content/api/5x/api/express/index.mdx @@ -55,10 +55,26 @@ The Express object has the following methods that can be used to create middlewa The `reviver` option is passed directly to `JSON.parse` as the second argument. You can find more information on this argument [in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#the_reviver_parameter). + + ```js + app.use(express.json({ + reviver: (key, value) => key === 'createdAt' ? new Date(value) : value, + })); + // Body: {"createdAt":"2026-01-01T00:00:00Z"} + // req.body.createdAt is a Date. + ``` + Enables or disables only accepting arrays and objects; when disabled will accept anything `JSON.parse` accepts. + + ```js + app.use(express.json({ strict: false })); + // Body: 42 -> req.body is the number 42. + // With strict: true (the default), this body is rejected with status 400. + ``` + This is used to determine what media type the middleware will parse. This option can be a @@ -72,6 +88,16 @@ The Express object has the following methods that can be used to create middlewa This option, if supplied, is called as `verify(req, res, buf, encoding)`, where `buf` is a `Buffer` of the raw request body and `encoding` is the encoding of the request. The parsing can be aborted by throwing an error. + + ```js + app.use(express.json({ + verify: (req, res, buf) => { + req.rawBody = buf; + }, + })); + // req.rawBody contains the original Buffer, before JSON parsing. + ``` + @@ -249,15 +275,43 @@ app.post('/upload', (req: Request, res: Response) => { Enable case sensitivity. Disabled by default, treating `/Foo` and `/foo` as the same. + + ```js + // caseSensitive: treat "/Foo" and "/foo" as different routes + const router = express.Router({ caseSensitive: true }); + router.get('/Foo', (req, res) => res.send('Matched /Foo exactly')); + ``` + Preserve the `req.params` values from the parent router. If the parent and the child have conflicting param names, the child's value take precedence. + + ```js + // mergeParams: access parent route params in child router + const parent = express.Router(); + const child = express.Router({ mergeParams: true }); + + parent.use('/user/:userId', child); + child.get('/comments', (req, res) => { + // req.params.userId is available because mergeParams: true + res.send(`Comments for user ${req.params.userId}`); + }); + ``` + Enable strict routing. Disabled by default, `/foo` and `/foo/` are treated the same by the router. + + ```js + // strict: treat "/foo" and "/foo/" as different routes + const strictRouter = express.Router({ strict: true }); + strictRouter.get('/foo/', (req, res) => res.send('Matched /foo/ with trailing slash')); + ``` + + @@ -304,12 +358,32 @@ For more information, see [Router](/api/router/). Let client errors fall-through as unhandled requests, otherwise forward a client error. See [fallthrough](#fallthrough) below. + + ```js + app.use('/assets', express.static('public', { fallthrough: true })); + app.use('/assets', (req, res) => { + res.status(404).send('Asset not found'); + }); + // Missing files reach the fallback above. + // With fallthrough: false, they reach error-handling middleware instead. + ``` + Enable or disable the `immutable` directive in the `Cache-Control` response header. If enabled, the `maxAge` option should also be specified to enable caching. The `immutable` directive will prevent supported clients from making conditional requests during the life of the `maxAge` option to check if the file has changed. + + ```js + // Use filenames that change whenever the file contents change. + app.use('/assets', express.static('public', { + maxAge: '1y', + immutable: true, + })); + // Cache-Control: public, max-age=31536000, immutable + ``` + Sends the specified directory index file. Set to `false` to disable directory indexing. @@ -579,6 +653,18 @@ app.post('/', (req: Request, res: Response) => { rich objects and arrays to be encoded into the URL-encoded format, allowing for a JSON-like experience with URL-encoded. For more information, please [see the qs library](https://www.npmjs.com/package/qs#readme). + + ```js + // Form body: user[name]=Tobi + app.post('/simple', express.urlencoded({ extended: false }), (req, res) => { + res.json(req.body); // => { 'user[name]': 'Tobi' } + }); + + app.post('/extended', express.urlencoded({ extended: true }), (req, res) => { + res.json(req.body); // => { user: { name: 'Tobi' } } + }); + ``` + Enables or disables handling deflated (compressed) bodies; when disabled, deflated bodies diff --git a/src/content/api/5x/api/request/index.mdx b/src/content/api/5x/api/request/index.mdx index 39916cc7aa..27e19c359f 100644 --- a/src/content/api/5x/api/request/index.mdx +++ b/src/content/api/5x/api/request/index.mdx @@ -897,6 +897,17 @@ For more information, or if you have issues or concerns, see [type-is](https://g Specify if overlapping and adjacent ranges should be combined. When `true`, ranges are combined and returned as if they were specified that way in the header. + + ```js + // Range: bytes=0-99,50-149 + const separate = req.range(1000, { combine: false }); + console.log(separate[0]); // => { start: 0, end: 99 } + console.log(separate[1]); // => { start: 50, end: 149 } + + const combined = req.range(1000, { combine: true }); + console.log(combined[0]); // => { start: 0, end: 149 } + ``` +