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

Update route guide #1626

Open
wants to merge 6 commits 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
78 changes: 46 additions & 32 deletions en/guide/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ For an introduction to routing, see [Basic routing](/{{ page.lang }}/starter/bas

You define routing using methods of the Express `app` object that correspond to HTTP methods;
for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list,
see [app.METHOD](/{{ page.lang }}/4x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/4x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/4x/api.html#app.use) to
see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/5x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/5x/api.html#app.use) to
specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details).

These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to the specified route (endpoint) and HTTP method. In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function.
Expand All @@ -39,7 +39,7 @@ app.get('/', (req, res) => {

A route method is derived from one of the HTTP methods, and is attached to an instance of the `express` class.

The following code is an example of routes that are defined for the GET and the POST methods to the root of the app.
The following code is an example of routes that are defined for the `GET` and the `POST` methods to the root of the app.

```js
// GET method route
Expand All @@ -54,9 +54,9 @@ app.post('/', (req, res) => {
```

Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on.
For a full list, see [app.METHOD](/{{ page.lang }}/4x/api.html#app.METHOD).
For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD).

There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route "/secret" whether using GET, POST, PUT, DELETE, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods).
There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods).

```js
app.all('/secret', (req, res, next) => {
Expand All @@ -69,19 +69,24 @@ app.all('/secret', (req, res, next) => {

Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions.
Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings or regular expressions.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was thinking about removing that part when I edited this file for the first time. Although it doesn’t work in Express 5, string patterns are present in version 4

Copy link
Member

Choose a reason for hiding this comment

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

Makes sense, I think "string pattern" is confusing... they're both strings. It's just Express 4 and 5 support strings of different syntax within the strings. I was thinking it'd be clearer to just note that the strings are different DSLs, and Express 4 happened to support regex characters, and if you wanted those characters literally they needed to be escaped.

Copy link
Member

Choose a reason for hiding this comment

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

It also depends on whether this doc is v5 first or v4 first I guess, but since the doc doesn't touch much on things that changed between the versions (i.e. * -> *name, etc) it might be easier to have it be things supported by each overall with caveats afterward for 4 vs 5 specifics?

Copy link
Member Author

Choose a reason for hiding this comment

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

Although a note was added below stating that string patterns are not supported in version 5, so I'm not sure if it would be good to make the change you suggested.

If you want to make any further changes that you think are important to improve the router guide, it's enabled for maintainers to make edits. You know more about how the router works

Copy link
Member Author

Choose a reason for hiding this comment

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

cc: @expressjs/docs-wg


The characters `?`, `+`, `*`, and `()` are subsets of their regular expression counterparts. The hyphen (`-`) and the dot (`.`) are interpreted literally by string-based paths.
{% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %}

If you need to use the dollar character (`$`) in a path string, enclose it escaped within `([` and `])`. For example, the path string for requests at "`/data/$book`", would be "`/data/([\$])book`".
{% include admonitions/caution.html content=caution-character %}

<div class="doc-box doc-info" markdown="1">
Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) is a handy tool for testing basic Express routes, although it does not support pattern matching.
</div>
{% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`.
{% endcapture %}

<div class="doc-box doc-warn" markdown="1">
Query strings are not part of the route path.
</div>
{% include admonitions/caution.html content=note-dollar-character %}

{% capture note-path-to-regexp %}
Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths.
{% endcapture %}

Here are some examples of route paths based on strings.
{% include admonitions/note.html content=note-path-to-regexp %}

{% include admonitions/warning.html content="Query strings are not part of the route path." %}

### Route paths based on strings

This route path will match requests to the root route, `/`.

Expand All @@ -107,7 +112,11 @@ app.get('/random.text', (req, res) => {
})
```

Here are some examples of route paths based on string patterns.
### Route paths based on string patterns

{% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %}

{% include admonitions/caution.html content=caution-string-patterns %}

This route path will match `acd` and `abcd`.

Expand Down Expand Up @@ -141,7 +150,7 @@ app.get('/ab(cd)?e', (req, res) => {
})
```

Examples of route paths based on regular expressions:
### Route paths based on regular expressions

This route path will match anything with an "a" in it.

Expand Down Expand Up @@ -195,6 +204,11 @@ Request URL: http://localhost:3000/plantae/Prunus.persica
req.params: { "genus": "Prunus", "species": "persica" }
```

{% capture warning-regexp %}
In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %}

{% include admonitions/caution.html content=warning-regexp %}

To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`):

```
Expand All @@ -203,13 +217,13 @@ Request URL: http://localhost:3000/user/42
req.params: {"userId": "42"}
```

<div class="doc-box doc-warn" markdown="1">
Because the regular expression is usually part of a literal string, be sure to escape any <code>\</code> characters with an additional backslash, for example <code>\\d+</code>.
</div>
{% include admonitions/warning.html content="Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`." %}

<div class="doc-box doc-warn" markdown="1">
In Express 4.x, <a href="https://github.com/expressjs/express/issues/2495">the <code>*</code> character in regular expressions is not interpreted in the usual way</a>. As a workaround, use <code>{0,}</code> instead of <code>*</code>. This will likely be fixed in Express 5.
</div>
{% capture warning-version %}
In Express 4.x, <a href="https://github.com/expressjs/express/issues/2495">the `*` character in regular expressions is not interpreted in the usual way</a>. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5.
{% endcapture %}

{% include admonitions/warning.html content=warning-version %}

<h2 id="route-handlers">Route handlers</h2>

Expand Down Expand Up @@ -283,20 +297,20 @@ The methods on the response object (`res`) in the following table can send a res

| Method | Description |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| [res.download()](/{{ page.lang }}/4x/api.html#res.download) | Prompt a file to be downloaded. |
| [res.end()](/{{ page.lang }}/4x/api.html#res.end) | End the response process. |
| [res.json()](/{{ page.lang }}/4x/api.html#res.json) | Send a JSON response. |
| [res.jsonp()](/{{ page.lang }}/4x/api.html#res.jsonp) | Send a JSON response with JSONP support. |
| [res.redirect()](/{{ page.lang }}/4x/api.html#res.redirect) | Redirect a request. |
| [res.render()](/{{ page.lang }}/4x/api.html#res.render) | Render a view template. |
| [res.send()](/{{ page.lang }}/4x/api.html#res.send) | Send a response of various types. |
| [res.sendFile()](/{{ page.lang }}/4x/api.html#res.sendFile) | Send a file as an octet stream. |
| [res.sendStatus()](/{{ page.lang }}/4x/api.html#res.sendStatus) | Set the response status code and send its string representation as the response body. |
| [res.download()](/{{ page.lang }}/5x/api.html#res.download) | Prompt a file to be downloaded. |
| [res.end()](/{{ page.lang }}/5x/api.html#res.end) | End the response process. |
| [res.json()](/{{ page.lang }}/5x/api.html#res.json) | Send a JSON response. |
| [res.jsonp()](/{{ page.lang }}/5x/api.html#res.jsonp) | Send a JSON response with JSONP support. |
| [res.redirect()](/{{ page.lang }}/5x/api.html#res.redirect) | Redirect a request. |
| [res.render()](/{{ page.lang }}/5x/api.html#res.render) | Render a view template. |
| [res.send()](/{{ page.lang }}/5x/api.html#res.send) | Send a response of various types. |
| [res.sendFile()](/{{ page.lang }}/5x/api.html#res.sendFile) | Send a file as an octet stream. |
| [res.sendStatus()](/{{ page.lang }}/5x/api.html#res.sendStatus) | Set the response status code and send its string representation as the response body. |

<h2 id="app-route">app.route()</h2>

You can create chainable route handlers for a route path by using `app.route()`.
Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/{{ page.lang }}/4x/api.html#router).
Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/{{ page.lang }}/5x/api.html#router).

Here is an example of chained route handlers that are defined by using `app.route()`.

Expand Down Expand Up @@ -356,7 +370,7 @@ app.use('/birds', birds)

The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route.

But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](https://expressjs.com/en/4x/api.html#app.use).
But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/{{ page.lang }}/5x/api.html#app.use).

```js
const router = express.Router({ mergeParams: true })
Expand Down
Loading