Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add examples for migration v5 #1712

Open
wants to merge 1 commit into
base: gh-pages
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 179 additions & 5 deletions en/guide/migrating-5.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ Express 5 is not very different from Express 4; although it maintains the same b

To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory:

```console
$ npm install "express@^{{ site.data.express.next_version }}"
```sh
npm install "express@^{{ site.data.express.next_version }}"
```

You can then run your automated tests to see what fails, and fix problems according to the updates listed below. After addressing test failures, run your app to see what errors occur. You'll find out right away if the app uses any methods or properties that are not supported.
Expand Down Expand Up @@ -61,7 +61,7 @@ You can then run your automated tests to see what fails, and fix problems accord
<li><a href="#brotli-support">Brotli encoding support</a></li>
</ul>

<h3>Removed methods and properties</h3>
### Removed methods and properties

If you use any of these methods or properties in your app, it will crash. So, you'll need to change your app after you update to version 5.

Expand All @@ -71,6 +71,18 @@ Express 5 no longer supports the `app.del()` function. If you use this function,

Initially, `del` was used instead of `delete`, because `delete` is a reserved keyword in JavaScript. However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names.

```js
// v4
app.del('/user/:id', (req, res) => {
res.send(`DELETE /user/${req.params.id}`)
})

// v5
app.delete('/user/:id', (req, res) => {
res.send(`DELETE /user/${req.params.id}`)
})
```

<h4 id="app.param">app.param(fn)</h4>

The `app.param(fn)` signature was used for modifying the behavior of the `app.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all.
Expand All @@ -85,6 +97,26 @@ The following method names have been pluralized. In Express 4, using the old met

`req.acceptsLanguage()` is replaced by `req.acceptsLanguages()`.

```js
// v4
app.all('/', (req, res) => {
req.acceptsCharset('utf-8')
req.acceptsEncoding('br')
req.acceptsLanguage('en')

// ...
})

// v5
app.all('/', (req, res) => {
req.acceptsCharsets('utf-8')
req.acceptsEncodings('br')
req.acceptsLanguages('en')

// ...
})
```

<h4 id="leading">Leading colon (:) in the name for app.param(name, fn)</h4>

A leading colon character (:) in the name for the `app.param(name, fn)` function is a remnant of Express 3, and for the sake of backwards compatibility, Express 4 supported it with a deprecation notice. Express 5 will silently ignore it and use the name parameter without prefixing it with a colon.
Expand All @@ -95,44 +127,186 @@ This should not affect your code if you follow the Express 4 documentation of [a

This potentially confusing and dangerous method of retrieving form data has been removed. You will now need to specifically look for the submitted parameter name in the `req.params`, `req.body`, or `req.query` object.

```js
// v4
app.post('/user', (req, res) => {
const id = req.param('id')
const body = req.param('body')
const query = req.param('query')

// ...
})

// v5
app.post('/user', (req, res) => {
const id = req.params.id
const body = req.body
const query = req.query

// ...
})
```

<h4 id="res.json">res.json(obj, status)</h4>

Express 5 no longer supports the signature `res.json(obj, status)`. Instead, set the status and then chain it to the `res.json()` method like this: `res.status(status).json(obj)`.

```js
// v4
app.post('/user', (req, res) => {
res.json({ name: 'Ruben' }, 201)
})

// v5
app.post('/user', (req, res) => {
res.status(201).json({ name: 'Ruben' })
})
```

<h4 id="res.jsonp">res.jsonp(obj, status)</h4>

Express 5 no longer supports the signature `res.jsonp(obj, status)`. Instead, set the status and then chain it to the `res.jsonp()` method like this: `res.status(status).jsonp(obj)`.

```js
// v4
app.post('/user', (req, res) => {
res.jsonp({ name: 'Ruben' }, 201)
})

// v5
app.post('/user', (req, res) => {
res.status(201).jsonp({ name: 'Ruben' })
})
```

<h4 id="res.redirect">res.redirect(url, status)</h4>

Express 5 no longer supports the signature `res.redirect(url, status)`. Instead, use the following signature: `res.redirect(status, url)`.

```js
// v4
app.get('/user', (req, res) => {
res.redirect('/users', 301)
})

// v5
app.get('/user', (req, res) => {
res.redirect(301, '/users')
})
```


<h4 id="magic-redirect">res.redirect('back') and res.location('back')</h4>

Express 5 no longer supports the magic string `back` in the `res.redirect()` and `res.location()` methods. Instead, use the `req.get('Referrer') || '/'` value to redirect back to the previous page. In Express 4, the res.`redirect('back')` and `res.location('back')` methods were deprecated.

```js
// v4
app.get('/user', (req, res) => {
res.redirect('back')
})

// v5
app.get('/user', (req, res) => {
res.redirect(req.get('Referrer') || '/')
})
```

<h4 id="res.send.body">res.send(body, status)</h4>

Express 5 no longer supports the signature `res.send(obj, status)`. Instead, set the status and then chain it to the `res.send()` method like this: `res.status(status).send(obj)`.

```js
// v4
app.get('/user', (req, res) => {
res.send({ name: 'Ruben' }, 200)
})

// v5
app.get('/user', (req, res) => {
res.status(200).send({ name: 'Ruben' })
})
```

<h4 id="res.send.status">res.send(status)</h4>

Express 5 no longer supports the signature `res.send(status)`, where `status` is a number. Instead, use the `res.sendStatus(statusCode)` function, which sets the HTTP response header status code and sends the text version of the code: "Not Found", "Internal Server Error", and so on.
If you need to send a number by using the `res.send()` function, quote the number to convert it to a string, so that Express does not interpret it as an attempt to use the unsupported old signature.

```js
// v4
app.get('/user', (req, res) => {
res.send(200)
})

// v5
app.get('/user', (req, res) => {
res.sendStatus(200)
})
```

<h4 id="res.sendfile">res.sendfile()</h4>

The `res.sendfile()` function has been replaced by a camel-cased version `res.sendFile()` in Express 5.

```js
// v4
app.get('/user', (req, res) => {
res.sendfile('/path/to/file')
})

// v5
app.get('/user', (req, res) => {
res.sendFile('/path/to/file')
})
```

<h3>Changed</h3>

<h4 id="path-syntax">Path route matching syntax</h4>

Path route matching syntax is when a string is supplied as the first parameter to the `app.all()`, `app.use()`, `app.METHOD()`, `router.all()`, `router.METHOD()`, and `router.use()` APIs. The following changes have been made to how the path string is matched to an incoming request:

- The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*`
- The optional character `?` is no longer supported, use braces instead: `/:file{.:ext}`.

```js
// v4
app.get('/*', async (req, res) => {
res.send('ok')
})

// v5
app.get('/*splat', async (req, res) => {
res.send('ok')
})
```

{% capture note_wildcard %}
If your defined route is `/*splat`, it will not include `/`, so you will need to make the route optional.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@blakeembrey
Is this wording correct? It’s a recurring problem i’ve seen, which is why I wanted to add that note, but I’m not sure if this is the best phrasing.


```js
// v5
app.get('/{*splat}', async (req, res) => {
res.send('ok')
})
```
{% endcapture %}
{% include admonitions/note.html content=note_wildcard %}

- The optional character `?` is no longer supported, use braces instead.

```js
// v4
app.get('/:file.:ext?', async (req, res) => {
res.send('ok')
})

// v5
app.get('/:file{.:ext}', async (req, res) => {
res.send('ok')
})
```

- Regexp characters are not supported. For example:
```js
app.get('/[discussion|page]/:slug', async (req, res) => {
Expand Down Expand Up @@ -187,7 +361,7 @@ The `res.status` method only accepts integers in the range of `100` to `999`, fo

The `res.vary` throws an error when the `field` argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console

<h3>Improvements</h3>
### Improvements

<h4 id="res.render">res.render()</h4>

Expand Down
Loading