ルーティング
Routing とは、アプリケーションのエンドポイント(URI)がクライアントリクエストに対してどのように応答するかを指します。 For an introduction to routing, see Basic routing. For an introduction to routing, see Basic routing.
HTTPメソッドに対応するExpress app オブジェクトのメソッドを使用してルーティングを定義します。
のように、app。 POST リクエストを処理する GET リクエストと app.post` を処理します。 You can also use app.all() to handle all HTTP methods and app.use() to
specify middleware as the callback function (See Using middleware for details). You can also use app.all() to handle all HTTP methods and app.use() to
specify middleware as the callback function (See Using middleware for details).
言い換えれば、アプリケーションは指定されたルートとメソッドに一致するリクエストを「リッスン」します。 マッチを検出すると、指定されたコールバック関数を呼び出します。 These routing methods specify a callback function (sometimes called a “handler function”) that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method.
実際、ルーティングメソッドは引数として複数のコールバック関数を持つことができます。
複数のコールバック関数を使用。 コールバック関数に next を引数として渡し、関数の本体内で next() を呼び出して、次のコールバックに
を渡すことが重要です。複数のコールバック関数を使用。 コールバック関数に next を引数として渡し、関数の本体内で next() を呼び出して、次のコールバックに
を渡すことが重要です。
以下のコードは、非常に基本的なルートの例です。
const express = require('express');const app = express();
// respond with "hello world" when a GET request is made to the homepageapp.get('/', (req, res) => { res.send('hello world');});import express from 'express';
const app = express();
// respond with "hello world" when a GET request is made to the homepageapp.get('/', (req, res) => { res.send('hello world');});import express, { type Express, type Request, type Response } from 'express';
const app: Express = express();
// respond with "hello world" when a GET request is made to the homepageapp.get('/', (req: Request, res: Response) => { res.send('hello world');});ルートメソッド
routeメソッドはHTTPメソッドのいずれかから派生し、express クラスのインスタンスに追加されます。
以下のコードは、GET と POST メソッドを定義したルートの例です。
// GET method routeapp.get('/', (req, res) => { res.send('GET request to the homepage');});
// POST method routeapp.post('/', (req, res) => { res.send('POST request to the homepage');});import { type Request, type Response } from 'express';
// GET method routeapp.get('/', (req: Request, res: Response) => { res.send('GET request to the homepage');});
// POST method routeapp.post('/', (req: Request, res: Response) => { res.send('POST request to the homepage');});Expressは、get、postなど、すべてのHTTPリクエストメソッドに対応するメソッドをサポートしています。
You can also use app.all() to handle all HTTP methods and app.use() to
specify middleware as the callback function (See Using middleware for details).
特別なルーティングメソッドapp.all()は、すべてのHTTPリクエストメソッドに対して、指定したパスでミドルウェア関数を読み込むために使用されます。 For example, the following handler is executed for requests to the route "/secret" whether using GET, QUERY, POST, PUT, DELETE, or any other HTTP request method supported in the http module.
app.all('/secret', (req, res, next) => { console.log('Accessing the secret section ...'); next(); // pass control to the next handler});import { type Request, type Response, type NextFunction } from 'express';
app.all('/secret', (req: Request, res: Response, next: NextFunction) => { console.log('Accessing the secret section ...'); next(); // pass control to the next handler});ルートパス
ルートパスはリクエストメソッドと組み合わせて、リクエストを作成できるエンドポイントを定義します。 ルートパスは文字列または正規表現にすることができます。 Route paths can be strings or regular expressions. Route paths can be strings or regular expressions. They can also capture values from the URL, as described in Route parameters below.
Note
Express はルートパスに一致する path-to-regexp v8 を使用します。ルートパスの定義におけるすべての可能性については、path-to-regexp ドキュメントを参照してください。 Express Playground Routerは、パターンマッチングをサポートしていませんが、基本的なExpressルートをテストするための便利なツールです。 Express Playground Router is a handy tool for testing basic Express routes, although it does not support pattern matching. Express Playground Router is a handy tool for testing basic Express routes, although it does not support pattern matching.
文字列パス
文字列パスはリクエストと完全に一致します。 ドット(.)とハイフン(-)は文字通り解釈されます。文字列パスはリクエストと完全に一致します。 ドット(.)とハイフン(-)は文字通り解釈されます。 The dot (.) and hyphen (-) are interpreted literally.
Warning
app.get('/', (req, res) => { res.send('root');});
app.get('/about', (req, res) => { res.send('about');});
app.get('/random.text', (req, res) => { res.send('random.text');});import { type Request, type Response } from 'express';
app.get('/', (req: Request, res: Response) => { res.send('root');});
app.get('/about', (req: Request, res: Response) => { res.send('about');});
app.get('/random.text', (req: Request, res: Response) => { res.send('random.text');});Caution
The characters ?, +, *, [], (), and ! are reserved and cannot be used as literal characters in route paths, and braces are reserved for optional segments. Use \ to escape them if needed.
正規表現
正規表現をルートパスとして使用することもできます。 これは、より複雑なマッチングロジックが必要な場合に便利です。正規表現をルートパスとして使用することもできます。 これは、より複雑なマッチングロジックが必要な場合に便利です。 This is useful when you need more complex matching logic.
// Matches any path containing "a"app.get(/a/, (req, res) => { res.send('/a/');});
// Matches paths ending with "fly" (butterfly, dragonfly, etc.)app.get(/.*fly$/, (req, res) => { res.send('/.*fly$/');});import { type Request, type Response } from 'express';
// Matches any path containing "a"app.get(/a/, (req: Request, res: Response) => { res.send('/a/');});
// Matches paths ending with "fly" (butterfly, dragonfly, etc.)app.get(/.*fly$/, (req: Request, res: Response) => { res.send('/.*fly$/');});ルートパラメータ
Route parameters are named URL segments that are used to capture the values specified at their position in the URL. ルートパラメータは、URL 内の位置で指定された値をキャプチャするために使用される名前付きの URL セグメントです。 取得した値は req.params オブジェクト内に入力され、パス内でそれぞれのキーとして指定されたrouteパラメータの名前が入力されます。 They come in three forms: named parameters (:name), wildcards (*name), and optional segments, which wrap either of them in braces.
Named parameters
Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below.
Route path: /users/:userId/books/:bookIdRequest URL: http://localhost:3000/users/34/books/8989req.params: { "userId": "34", "bookId": "8989" }ルートパラメータを使用してルートを定義するには、以下のようにルートのパスにルートパラメータを指定します。
app.get('/users/:userId/books/:bookId', (req, res) => { res.send(req.params);});In TypeScript, @types/express infers the parameters from the route path, so in the handler above
req.params.userId and req.params.bookId are already typed as string with no extra annotation.
Reading a name that is not in the route (such as req.params.other) is a type error. You only need
to annotate the parameters when the handler is defined separately from the route, because the type
checker can no longer see the path. In that case, pass them as the first type argument of Request:
import { type Request, type Response } from 'express';
const sendParams = (req: Request<{ userId: string; bookId: string }>, res: Response) => { res.send(req.params);};
app.get('/users/:userId/books/:bookId', sendParams);Caution
The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example :"user-name".
ハイフン(-)とドット(.)は文字通り解釈されるので、ルートパラメータとともに便利な目的で使うことができます。
Route path: /flights/:from-:toRequest URL: http://localhost:3000/flights/LAX-SFOreq.params: { "from": "LAX", "to": "SFO" }Route path: /plantae/:genus.:speciesRequest URL: http://localhost:3000/plantae/Prunus.persicareq.params: { "genus": "Prunus", "species": "persica" }Caution
Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as :userId(\d+). Use an array of paths or a full regular expression instead.
See the path route matching syntax for more information.
ワイルドカード
Wildcards match any path after a prefix. Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string.
app.get('/files/*filepath', (req, res) => { // GET /files/images/logo.png console.dir(req.params.filepath); // => [ 'images', 'logo.png' ] res.send(`File: ${req.params.filepath.join('/')}`);});import { type Request, type Response } from 'express';
app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { // GET /files/images/logo.png console.dir(req.params.filepath); // => [ 'images', 'logo.png' ] res.send(`File: ${req.params.filepath.join('/')}`);});ルートパスに一致させるには、ワイルドカードを括弧で囲みます。
// Matches / , /foo , /foo/bar , etc.app.get('/{*splat}', (req, res) => { // GET / => req.params = {}, splat is omitted // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] res.send('ok');});import { type Request, type Response } from 'express';
// Matches / , /foo , /foo/bar , etc.app.get('/{*splat}', (req: Request, res: Response) => { // GET / => req.params = {}, splat is omitted // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] res.send('ok');});任意のセグメント
Use braces to define optional segments in a route path. ルートパスで任意のセグメントを定義するには、括弧を使用します。 セグメントが存在しない場合、パラメータは req.params から省略されます。
app.get('/:file{.:ext}', (req, res) => { // GET /image.png => req.params = { file: 'image', ext: 'png' } // GET /image => req.params = { file: 'image' } res.send('ok');});import { type Request, type Response } from 'express';
app.get('/:file{.:ext}', (req: Request, res: Response) => { // GET /image.png => req.params = { file: 'image', ext: 'png' } // GET /image => req.params = { file: 'image' } res.send('ok');});The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters:
app.get('/user/{:id}', (req, res) => { // GET /user/42 => req.params = { id: '42' } // GET /user/ => req.params = {} // GET /user => 404, only the parameter is optional res.send('ok');});
app.get('/order{/:id}', (req, res) => { // GET /order/42 => req.params = { id: '42' } // GET /order => req.params = {}, the whole segment is optional res.send('ok');});import { type Request, type Response } from 'express';
app.get('/user/{:id}', (req: Request, res: Response) => { // GET /user/42 => req.params = { id: '42' } // GET /user/ => req.params = {} // GET /user => 404, only the parameter is optional res.send('ok');});
app.get('/order{/:id}', (req: Request, res: Response) => { // GET /order/42 => req.params = { id: '42' } // GET /order => req.params = {}, the whole segment is optional res.send('ok');});ルートパス内のスラッシュの位置を、リクエスト URL に関するstrict routing 設定と混同しないでください。この設定は、ルートパスが要求していないスラッシュで終わる URL が一致するかどうかを制御します。たとえば、/order/ へのリクエストはデフォルトでは /order{/:id} ルートに一致しますが、strict routing が有効な場合は 404 エラーを返します。/user/ の末尾のスラッシュは、/user/{:id} ルートがそれを必須としているため影響を受けません。上記の例でコメントされているすべてのリクエストは、この設定に関係なく同じように動作します。
Route handlers
リクエストを処理するために、ミドルウェアのように動作する複数のコールバック関数を指定できます。 The only exception is that these callbacks might invoke next('route') to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there’s no reason to proceed with the current route.
app.get('/user/:id', (req, res, next) => { if (req.params.id === '0') { return next('route'); } res.send(`User ${req.params.id}`);});
app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0');});import { type Request, type Response, type NextFunction } from 'express';
app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { if (req.params.id === '0') { return next('route'); } res.send(`User ${req.params.id}`);});
app.get('/user/:id', (req: Request, res: Response) => { res.send('Special handler for user ID 0');});この例では:
GET /user/5→ 最初のルートで処理 → “User 5” を送信GET /user/0→ 最初のルートがnext('route')を呼び出し、次に一致する/user/:idルートへスキップします。
ルートハンドラは、次の例に示すように、関数、関数の配列、または両方の組み合わせの形式で使用できます。
単一のコールバック関数はルートを処理できます。例:
app.get('/example/a', (req, res) => { res.send('Hello from A!');});import { type Request, type Response } from 'express';
app.get('/example/a', (req: Request, res: Response) => { res.send('Hello from A!');});複数のコールバック関数がルートを処理できます (next オブジェクトを指定してください)。例:
app.get( '/example/b', (req, res, next) => { console.log('the response will be sent by the next function ...'); next(); }, (req, res) => { res.send('Hello from B!'); });import { type Request, type Response, type NextFunction } from 'express';
app.get( '/example/b', (req: Request, res: Response, next: NextFunction) => { console.log('the response will be sent by the next function ...'); next(); }, (req: Request, res: Response) => { res.send('Hello from B!'); });コールバック関数の配列はルートを処理できます。 例: 例:
const cb0 = function (req, res, next) { console.log('CB0'); next();};
const cb1 = function (req, res, next) { console.log('CB1'); next();};
const cb2 = function (req, res) { res.send('Hello from C!');};
app.get('/example/c', [cb0, cb1, cb2]);import { type Request, type Response, type NextFunction } from 'express';
const cb0 = function (req: Request, res: Response, next: NextFunction) { console.log('CB0'); next();};
const cb1 = function (req: Request, res: Response, next: NextFunction) { console.log('CB1'); next();};
const cb2 = function (req: Request, res: Response) { res.send('Hello from C!');};
app.get('/example/c', [cb0, cb1, cb2]);独立した関数と関数の配列の組み合わせは、ルートを処理することができます。 例: 例: 例:
const cb0 = function (req, res, next) { console.log('CB0'); next();};
const cb1 = function (req, res, next) { console.log('CB1'); next();};
app.get( '/example/d', [cb0, cb1], (req, res, next) => { console.log('the response will be sent by the next function ...'); next(); }, (req, res) => { res.send('Hello from D!'); });import { type Request, type Response, type NextFunction } from 'express';
const cb0 = function (req: Request, res: Response, next: NextFunction) { console.log('CB0'); next();};
const cb1 = function (req: Request, res: Response, next: NextFunction) { console.log('CB1'); next();};
app.get( '/example/d', [cb0, cb1], (req: Request, res: Response, next: NextFunction) => { console.log('the response will be sent by the next function ...'); next(); }, (req: Request, res: Response) => { res.send('Hello from D!'); });レスポンスメソッド
The methods on the response object (res) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging.
| 方法 | 説明 |
|---|---|
| res.download() | ダウンロードするファイルを指示します。 |
| res.end() | 応答プロセスを終了します。 |
| res.json() | JSON 応答を送信します。 |
| res.jsonp() | JSONP サポートを使用して JSON 応答を送信します。 |
| res.redirect() | Redirect a request. |
| res.render() | ビューテンプレートをレンダリングします。 |
| res.send() | さまざまなタイプの応答を送信します。 |
| res.sendFile() | ファイルをオクテットストリームとして送信する。 |
| res.sendStatus() | レスポンスステータスコードを設定し、文字列表現をレスポンスボディとして送信します。 |## app.route()You can create chainable route handlers for a rou |
app.route()
app.route() を使用すると、ルートパスに対してチェーン可能なルートハンドラを作成できます。
パスは単一の場所で指定されているため、モジュラールートを作成することは、冗長性とタイプミスを削減するのに役立ちます。 ルートの詳細については、以下を参照してください: Router() documentation。
Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos.
Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the Router() documentation.
以下は、app.route()を使用して定義されたルートハンドラの例です。
app .route('/book') .get((req, res) => { res.send('Get a random book'); }) .post((req, res) => { res.send('Add a book'); }) .put((req, res) => { res.send('Update the book'); });import { type Request, type Response } from 'express';
app .route('/book') .get((req: Request, res: Response) => { res.send('Get a random book'); }) .post((req: Request, res: Response) => { res.send('Add a book'); }) .put((req: Request, res: Response) => { res.send('Update the book'); });express.Router
express.Router クラスを使用して、モジュール化されたマウント可能なルートハンドラを作成します。 Routerインスタンスは完全なミドルウェアとルーティングシステムです。そのため、しばしば「ミニアプリ」と呼ばれます。
次の例では、ルータをモジュールとして作成し、ミドルウェア関数をロードします。 いくつかのルートを定義し、メインアプリのパスにルータモジュールをマウントします。
appディレクトリにbirds.jsという名前のルーターファイルを作成します。以下の内容を使用します。
const express = require('express');const router = express.Router();
// middleware that is specific to this routerconst timeLog = (req, res, next) => { console.log('Time: ', Date.now()); next();};router.use(timeLog);
// define the home page routerouter.get('/', (req, res) => { res.send('Birds home page');});// define the about routerouter.get('/about', (req, res) => { res.send('About birds');});
module.exports = router;import express from 'express';
const router = express.Router();
// middleware that is specific to this routerconst timeLog = (req, res, next) => { console.log('Time: ', Date.now()); next();};router.use(timeLog);
// define the home page routerouter.get('/', (req, res) => { res.send('Birds home page');});// define the about routerouter.get('/about', (req, res) => { res.send('About birds');});
export default router;import express, { type Request, type Response, type NextFunction } from 'express';
const router = express.Router();
// middleware that is specific to this routerconst timeLog = (req: Request, res: Response, next: NextFunction) => { console.log('Time: ', Date.now()); next();};router.use(timeLog);
// define the home page routerouter.get('/', (req: Request, res: Response) => { res.send('Birds home page');});// define the about routerouter.get('/about', (req: Request, res: Response) => { res.send('About birds');});
export default router;次に、アプリにルーターモジュールをロードします。
const birds = require('./birds');
// ...
app.use('/birds', birds);import birds from './birds';
// ...
app.use('/birds', birds);アプリは /birds と /birds/about へのリクエストを処理できるようになりました。 同様に、ルート固有の「timeLog」ミドルウェア関数を呼び出します。
ただし、親ルート /birds にパスパラメータがある場合、サブルートからデフォルトではアクセスできません。 アクセス可能にするには、 mergeParams オプションを Router コンストラクタ reference に渡す必要があります。ただし、親ルート /birds にパスパラメータがある場合、サブルートからデフォルトではアクセスできません。 アクセス可能にするには、 mergeParams オプションを Router コンストラクタ reference に渡す必要があります。 To make it accessible, you will need to pass the mergeParams option to the Router constructor.
const router = express.Router({ mergeParams: true });