ルーティング
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` を処理します。 For a full list,
see app.METHOD. 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は、すべてのHTTPリクエストメソッドに対応するメソッドをサポートしています: get、postなど。
完全なリストについては、 app.METHOD を参照してください。
For a full list, see app.METHOD.
特別なルーティングメソッドapp.all()があり、_all_HTTPリクエストメソッドのパスにミドルウェア関数をロードするために使用されます。 例えば、GETを使用しているかどうかに関わらず、ルート"/secret"へのリクエストに対して以下のハンドラが実行されます。 POST、PUT、DELETE`、またはhttp moduleでサポートされている他の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.
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.
文字列パス
文字列パスはリクエストと完全に一致します。 ドット(.)とハイフン(-)は文字通り解釈されます。 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');});ワイルドカード
Wildcards match any path after a prefix. ワイルドカードはプレフィックスの後の任意のパスに一致します。 ルートパラメータと同様に名前が必要で、パスセグメントの配列として取得されます。
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 = [] // 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 = [] // 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');});?、+、*、[]、()の文字は予約されており、ルートパスの文字列として使用することはできません。 必要に応じてエスケープするには\を使用します。 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パラメータの名前が入力されます。
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);ルートパラメータの名前は、“単語文字” ([A-Za-z0-9_] )で構成されている必要があります。
ハイフン(-)とドット(.)は文字通り解釈されるので、ルートパラメータとともに便利な目的で使うことができます。
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" }正規表現文字はルートパスではサポートされていません。 代わりにパスまたは正規表現の配列を使用してください。 詳細については、パスルートマッチング構文を参照してください。 Use an array of paths or regular expressions instead. See the path route matching syntax for more information.
Route handlers
リクエストを処理するために、 middleware のように動作する複数のコールバック関数を提供できます。 唯一の例外は、これらのコールバックが next('route') を呼び出して、残りのルートコールバックをバイパスすることです。 このメカニズムを使用して、ルート上に事前条件を設定できます。 次に現在のルートを進める理由がなければ次のルートに制御を渡す。 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→ 最初のroute (‘route’)を呼び出し、次に一致する/user/:id` route (ルート) をスキップします。
ルートハンドラは、次の例に示すように、関数、関数の配列、または両方の組み合わせの形式で使用できます。
単一のコールバック関数はルートを処理できます。 例: 例:
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!'); });レスポンスメソッド
次の表のレスポンスオブジェクト (res) のメソッドは、クライアントにレスポンスを送信し、リクエスト応答のサイクルを終了することができます。 これらのメソッドのいずれもルートハンドラから呼び出されない場合、クライアントリクエストはハングしたままになります。 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()
app.route() を使用すると、ルートパスに対してチェーン可能なルートハンドラを作成できます。
パスは単一の場所で指定されているため、モジュラールートを作成することは、冗長性とタイプミスを削減するのに役立ちます。 ルートの詳細については、以下を参照してください: Router() documentation。
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.
以下は、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
Use the express.Router class to create modular, mountable route handlers. 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 に渡す必要があります。 To make it accessible, you will need to pass the mergeParams option to the Router constructor reference.
const router = express.Router({ mergeParams: true });