From 40197d6831ac2ef209f6ac3aaeca1edade060f66 Mon Sep 17 00:00:00 2001 From: krzysdz Date: Sat, 1 Nov 2025 01:09:59 +0100 Subject: [PATCH 1/6] docs(migrating-5): document req.params changes in 5.x Fixes #2090 --- en/guide/migrating-5.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/en/guide/migrating-5.md b/en/guide/migrating-5.md index 99a5b8fb9f..faf0e3e1ca 100755 --- a/en/guide/migrating-5.md +++ b/en/guide/migrating-5.md @@ -71,6 +71,7 @@ You can find the list of available codemods [here](https://github.com/expressjs/
  • app.router
  • req.body
  • req.host
  • +
  • req.params
  • req.query
  • res.clearCookie
  • res.status
  • @@ -506,7 +507,7 @@ const server = app.listen(8080, '0.0.0.0', (error) => { The `app.router` object, which was removed in Express 4, has made a comeback in Express 5. In the new version, this object is a just a reference to the base Express router, unlike in Express 3, where an app had to explicitly load it. -

    req.body

    +

    req.body

    The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default. @@ -514,6 +515,22 @@ The `req.body` property returns `undefined` when the body has not been parsed. I In Express 4, the `req.host` function incorrectly stripped off the port number if it was present. In Express 5, the port number is maintained. +

    req.params

    + +Parameters specified as wildcards are represented as arrays of segments: + +```js +app.get('/*splat', (req, res) => { + // GET /foo/bar + console.dir(req.params) + // => [Object: null prototype] { splat: [ 'foo', 'bar' ] } +}) +``` + +Optional parameters that are not matched do not have a key in `req.params`. In 4.x an unmatched wildcard would be an empty string and a `:` parameter made optional by `?` had a key with value `undefined`. + +The object has null prototype. +

    req.query

    The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". From 50de3edb3d995331f68b85b929070f4cf5b168a4 Mon Sep 17 00:00:00 2001 From: krzysdz Date: Sat, 1 Nov 2025 17:32:04 +0100 Subject: [PATCH 2/6] docs(api-5): document wildcard parameters in req.params --- _includes/api/en/5x/req-params.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/_includes/api/en/5x/req-params.md b/_includes/api/en/5x/req-params.md index 2f48c828d4..d68a4f24c5 100644 --- a/_includes/api/en/5x/req-params.md +++ b/_includes/api/en/5x/req-params.md @@ -1,6 +1,6 @@

    req.params

    -This property is an object containing properties mapped to the [named route "parameters"](/{{ page.lang }}/guide/routing.html#route-parameters). For example, if you have the route `/user/:name`, then the "name" property is available as `req.params.name`. This object defaults to `{}`. +This property is an object containing properties mapped to the [named route "parameters"](/{{ page.lang }}/guide/routing.html#route-parameters). For example, if you have the route `/user/:name`, then the "name" property is available as `req.params.name`. This object defaults to `Object.create(null)`. ```js // GET /user/tj @@ -8,6 +8,18 @@ console.dir(req.params.name) // => "tj" ``` +Properties corresponding to wildcard parameters are arrays containing separate path segments split on `/`: + +```js +app.get('/files/*file', (req, res) => { + console.dir(req.params.file) + // GET /files/note.txt + // => [ 'note.txt' ] + // GET /files/images/image.png + // => [ 'images', 'image.png' ] +}) +``` + When you use a regular expression for the route definition, capture groups are provided in the array using `req.params[n]`, where `n` is the nth capture group. ```js From 9628fafb30ab6912e24c4c2d82bc1ddb00e6ac31 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 18 Dec 2025 18:38:19 -0500 Subject: [PATCH 3/6] docs(migrating-5): update req.params examples for v5 wildcard syntax --- en/guide/migrating-5.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/en/guide/migrating-5.md b/en/guide/migrating-5.md index faf0e3e1ca..128b4b3b6e 100755 --- a/en/guide/migrating-5.md +++ b/en/guide/migrating-5.md @@ -529,6 +529,22 @@ app.get('/*splat', (req, res) => { Optional parameters that are not matched do not have a key in `req.params`. In 4.x an unmatched wildcard would be an empty string and a `:` parameter made optional by `?` had a key with value `undefined`. +```js +// v4 +app.get('/:file.:ext?', (req, res) => { + // GET /image + console.dir(req.params) + // => { file: 'image', ext: undefined } +}) + +// v5 +app.get('/:file{.:ext}', (req, res) => { + // GET /image + console.dir(req.params) + // => [Object: null prototype] { file: 'image' } +}) +``` + The object has null prototype.

    req.query

    From edf35b5e875452e52ebc2c0a3abe325df49d9396 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 18 Dec 2025 20:36:43 -0500 Subject: [PATCH 4/6] docs: apply suggetions --- en/guide/migrating-5.md | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/en/guide/migrating-5.md b/en/guide/migrating-5.md index 1b49794790..ce4465ca32 100755 --- a/en/guide/migrating-5.md +++ b/en/guide/migrating-5.md @@ -518,7 +518,11 @@ In Express 4, the `req.host` function incorrectly stripped off the port number i

    req.params

    -Parameters specified as wildcards are represented as arrays of segments: +The `req.params` object now has a **null prototype**. Additionally, there are two important behavioral changes: + +**Wildcard parameters are now arrays:** + +Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string. ```js app.get('/*splat', (req, res) => { @@ -528,17 +532,26 @@ app.get('/*splat', (req, res) => { }) ``` -Optional parameters that are not matched do not have a key in `req.params`. In 4.x an unmatched wildcard would be an empty string and a `:` parameter made optional by `?` had a key with value `undefined`. +**Unmatched parameters are omitted:** + +In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` parameters (using `?`) had a key with value `undefined`. In Express 5, unmatched parameters are completely omitted from `req.params`. ```js -// v4 +// v4: unmatched wildcard is empty string +app.get('/*', (req, res) => { + // GET / + console.dir(req.params) + // => { '0': '' } +}) + +// v4: unmatched optional param is undefined app.get('/:file.:ext?', (req, res) => { // GET /image console.dir(req.params) // => { file: 'image', ext: undefined } }) -// v5 +// v5: unmatched optional param is omitted app.get('/:file{.:ext}', (req, res) => { // GET /image console.dir(req.params) @@ -546,8 +559,6 @@ app.get('/:file{.:ext}', (req, res) => { }) ``` -The object has null prototype. -

    req.query

    The `req.query` property is no longer a writable property and is instead a getter. The default query parser has been changed from "extended" to "simple". From 80a5f3794075489038951382f9defccc98305798 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 18 Dec 2025 20:51:07 -0500 Subject: [PATCH 5/6] docs(migrating-5): clarify req.params behavior with string paths and regex --- en/guide/migrating-5.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/guide/migrating-5.md b/en/guide/migrating-5.md index ce4465ca32..515856386a 100755 --- a/en/guide/migrating-5.md +++ b/en/guide/migrating-5.md @@ -518,7 +518,7 @@ In Express 4, the `req.host` function incorrectly stripped off the port number i

    req.params

    -The `req.params` object now has a **null prototype**. Additionally, there are two important behavioral changes: +The `req.params` object now has a **null prototype** when using string paths. However, if the path is defined with a regular expression, `req.params` remains a standard object with a normal prototype. Additionally, there are two important behavioral changes: **Wildcard parameters are now arrays:** From b7d13cfeb038c44493697970e534547ff7dc0242 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 18 Dec 2025 20:53:19 -0500 Subject: [PATCH 6/6] docs(req.params): clarify default object behavior with string paths and regex --- _includes/api/en/5x/req-params.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/api/en/5x/req-params.md b/_includes/api/en/5x/req-params.md index 9bf2efb70e..4037832cb4 100644 --- a/_includes/api/en/5x/req-params.md +++ b/_includes/api/en/5x/req-params.md @@ -1,6 +1,6 @@

    req.params

    -This property is an object containing properties mapped to the [named route "parameters"](/{{ page.lang }}/guide/routing.html#route-parameters). For example, if you have the route `/user/:name`, then the "name" property is available as `req.params.name`. This object defaults to `Object.create(null)`. +This property is an object containing properties mapped to the [named route "parameters"](/{{ page.lang }}/guide/routing.html#route-parameters). For example, if you have the route `/user/:name`, then the "name" property is available as `req.params.name`. This object defaults to `Object.create(null)` when using string paths, but remains a standard object with a normal prototype when the path is defined with a regular expression. ```js // GET /user/tj