概要: このチュートリアルでは、Expressルーティングについて学びます。これは、エンドポイント(URI)を定義し、クライアントがそれらのエンドポイントをリクエストしたときに応答するプロセスです。
Expressルーティングの概要
エンドポイントとは、特定のURL(Uniform Resource Locator)またはパスと、HTTPメソッド(GET、POST、PUT、…)のことです。
通常、エンドポイントは、クライアントがデータの取得、データの変更、レコードの削除などの特定の操作を実行できる特定のリソースまたは機能を意味します。
たとえば、次のエンドポイントはToDoリストを取得します。
GET /todos
このエンドポイントでは、パスは/todos
で、HTTPメソッドはGET
です。
次のエンドポイントは、新しいToDo項目を作成します。
POST /todos
パスは/todos
ですが、HTTPメソッドはPOST
です。
Expressでは、ルーティングは、エンドポイントを設定し、クライアントがそれらのエンドポイントをリクエストしたときにアプリケーションがどのように応答するかを定義することです。
ルートは、アプリケーションがエンドポイントへのリクエストをどのように処理するかを定義します。ルートを定義するには、get、post、put、patch、deleteなどのExpress
オブジェクトのメソッドと、
ルートを定義するための構文を以下に示します。
app.method(path, handler);
Code language: JavaScript (javascript)
この構文では、
app
は、Express
アプリケーションのインスタンスです。method
は、get
、post
、put
、patch
、delete
などの小文字のHTTPリクエストメソッドです。path
は、サーバー上のパスです。handler
は、ルートが一致したときに実行される関数です。ルートハンドラーは、HTTPリクエストおよびレスポンスオブジェクトに対応するreq
およびres
オブジェクトにアクセスできます。
基本的なルートの例
以下は、ルートURL('/')へのGET
リクエストのルートを定義します。
app.get('/', (req, res) => {
res.send('Hello World');
});
Code language: PHP (php)
同様に、以下は'/about'
へのGET
リクエストのルートを定義します。
app.get('/about', (req, res) => {
res.send('About Page');
});
Code language: PHP (php)
次の例は、'/login'
へのPOST
リクエストのルートを定義します。
app.post('/login', (req, res) => {
res.send('Authenticated');
});
Code language: PHP (php)
Expressルーティングの例
いくつかのルートを持つExpressアプリケーションを作成してみましょう。
Expressアプリケーションの作成
ステップ1. ターミナルまたはコマンドプロンプトを開き、express-routing
などの新しいディレクトリを作成します。
mkdir express-routing
cd express-routing
Code language: JavaScript (javascript)
ステップ2. 次のnpm
コマンドを実行して、プロジェクトを初期化します。
npm init -y
Code language: JavaScript (javascript)
これにより、構成、スクリプト、依存関係を含むpackage.jsonファイルが作成されます。
ステップ3. ターミナルから次のnpm
コマンドを実行して、Expressをインストールします。
npm install express
Code language: JavaScript (javascript)
ステップ4. プロジェクトに.env
ファイルを追加し、PORT
を3000
に設定します。
PORT=3000
Code language: JavaScript (javascript)
ステップ5. Node.jsにESモジュールを使用するように指示するために、次のキー/値ペアをpackage.json
ファイルに追加します。
"type": "module"
Code language: JavaScript (javascript)
また、scripts
セクションを次のように変更します。
"scripts": {
"start": "node --watch index.js"
},
Code language: JavaScript (javascript)
これにより、npm start
コマンドを実行して、--watch
フラグを使用してindex.js
ファイルを実行できます。
ステップ6. 次のコードを含むindex.js
ファイルを作成します。
import express from 'express';
const app = express();
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
Code language: JavaScript (javascript)
ステップ7. ターミナルから次のコマンドを実行して、サーバーを起動します。
npm start
Code language: JavaScript (javascript)
ステップ8. VS CodeのREST Client拡張機能を使用してルートにリクエストを行うためのapi.http
ファイルを作成します。
ルートの追加
ステップ1. ToDo項目の配列と次のToDo IDを返す関数をエクスポートする新しいモジュールtodos.js
モジュールを作成します。
export const todos = [
{ id: 1, title: 'Learn Node.js', completed: true },
{ id: 2, title: 'Master Express', completed: false },
{ id: 3, title: 'Build an API Server', completed: false },
];
export const nextTodoId = () => {
// get the next id for the todo
let maxId = 1;
todos.forEach((todo) => {
if (todo.id > maxId) {
maxId = todo.id;
}
});
return maxId + 1;
};
Code language: JavaScript (javascript)
ステップ2. todos.js
モジュールからtodos
配列とnextTodoId
関数をindex.js
モジュールにインポートします。
import { todos, nextTodoId } from './todos.js';
Code language: JavaScript (javascript)
ステップ3. '/api/todos/'
エンドポイントへのGETリクエストのルートを定義します。
import express from 'express';
import { todos, nextTodoId} from './todos.js';
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/api/todos/', (req, res) => {
res.send(todos);
});
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
Code language: JavaScript (javascript)
ステップ4. /api/todos
エンドポイントへのHTTPリクエストを追加して、api.http
を変更します。
# Get all todos items
GET http://localhost:3000/api/todos/
Code language: JavaScript (javascript)
/api/todos/
エンドポイントにGETリクエストが送信されると、ルートハンドラーが実行され、todos
配列をJSONデータとして応答します。
[
{
"id": 1,
"title": "Learn Node.js",
"completed": true
},
{
"id": 2,
"title": "Master Express",
"completed": false
},
{
"id": 3,
"title": "Build an API Server",
"completed": false
}
]
Code language: JavaScript (javascript)
ルートへのクエリ文字列の追加
完了または未完了のToDo項目のリストを取得するには、次のようにクエリ文字列を/api/todos
ルートに追加できます。
http://localhost:3000/api/todos/?completed=true
Code language: JavaScript (javascript)
または
http://localhost:3000/api/todos/?completed=false
Code language: JavaScript (javascript)
URL内の疑問符(?
)以降のすべては、クエリ文字列と呼ばれます。この例では、クエリ文字列は次のとおりです。
completed=false
Code language: JavaScript (javascript)
クエリ文字列には、1つ以上のパラメータを含めることができます。各パラメータは、等号(=
)で区切られた一意のキー/値ペアで表されます。
ExpressでURLからクエリ文字列にアクセスするには、次のようにreq.query
オブジェクトを使用します。
req.query
Code language: JavaScript (javascript)
例:
// ...
app.get('/api/todos/', (req, res) => {
console.log(req.query);
});
// ...
Code language: JavaScript (javascript)
http://localhost:3000/api/todos/?completed=false
エンドポイントにGETリクエストを行うと、コンソールに次のクエリオブジェクトが表示されます。
{ completed: 'false' }
Code language: JavaScript (javascript)
クエリ文字列のcompleted
パラメータにアクセスするには、次を使用できます。
app.get('/api/todos/', (req, res) => {
console.log(req.query.completed);
});
Code language: JavaScript (javascript)
以下は、completed
クエリ文字列が使用可能な場合に、未完了/完了のToDo項目を返すように/api/todos/
エンドポイントを変更します。
app.get('/api/todos/', (req, res) => {
if (req?.query?.completed) {
const isCompleted = req.query.completed === 'true';
const filteredTodos = todos.filter(
(todo) => todo.completed === isCompleted
);
res.send(filteredTodos);
}
res.send(todos);
});
Code language: JavaScript (javascript)
更新されたapi.http
ファイルのバージョンを以下に示します。
# Get all todos items
GET http://localhost:3000/api/todos/
###
# Get incompleted todo items:
GET http://localhost:3000/api/todos/?completed=false
###
# Get completed todo items:
GET http://localhost:3000/api/todos/?completed=true
Code language: JavaScript (javascript)
ルートパラメータの処理
ルートセグメントは、URL内の位置に指定された値をキャプチャするために使用される名前付きURLセグメントです。例えば
http://localhost:3000/api/todos/1
Code language: JavaScript (javascript)
このURLでは、1はToDo IDを表すルートパラメータです。
Expressでは、次のようにIDを使用してルートを設定できます。
/api/todo/:id
Code language: JavaScript (javascript)
ルートパラメータにアクセスするには、req.params
オブジェクトを使用します。
req.params
Code language: JavaScript (javascript)
ルート/api/todo/:id
では、id
はreq.params
オブジェクトのキーです。したがって、次を使用してアクセスできます。
req.params.id
Code language: JavaScript (javascript)
ルートパラメータの値は常に文字列であることに注意してください。したがって、目的の型の値に変換する必要があります。
以下は、IDによってToDo項目を返すルートを定義します。
app.get('/api/todos/:id', (req, res) => {
const { id } = req.params;
const todoId = parseInt(id);
if (isNaN(todoId)) {
res.status(400).send(`Invalid id ${id}`);
}
const todo = todos.find((todo) => todo.id === todoId);
if (todo) res.status(200).send(todo);
res.status(404).send(`Todo with id ${id} not found`);
});
Code language: JavaScript (javascript)
仕組み。
まず、オブジェクトを分割代入して、req.params
オブジェクトからIDを取得します。
const { id } = req.params;
Code language: JavaScript (javascript)
次に、ID値を整数に変換します。IDが数値でない場合は、エラーメッセージとともにHTTPステータスコード400で応答します。
const todoId = parseInt(id);
if (isNaN(todoId)) {
res.status(400).send(`Invalid id ${id}`);
}
Code language: JavaScript (javascript)
3番目に、IDを持つToDoを見つけ、JSONとしてクライアントに返します。
const todo = todos.find((todo) => todo.id === id);
if (todo) res.send(todo);
Code language: JavaScript (javascript)
最後に、IDを持つToDoが見つからない場合は、HTTPステータスコード404を返します。
res.status(404).send(`Todo with id ${id} not found`);
Code language: JavaScript (javascript)
すべてをまとめる
以下に、完成したindex.js
モジュールを示します。
import express from 'express';
import { todos, nextTodoId } from './todos.js';
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/api/todos/', (req, res) => {
if (req?.query?.completed) {
const isCompleted = req.query.completed === 'true';
const filteredTodos = todos.filter(
(todo) => todo.completed === isCompleted
);
res.send(filteredTodos);
}
res.send(todos);
});
app.get('/api/todos/:id', (req, res) => {
const { id } = req.params;
const todoId = parseInt(id);
if (isNaN(todoId)) {
res.status(400).send(`Invalid id ${id}`);
}
const todo = todos.find((todo) => todo.id === todoId);
if (todo) res.status(200).send(todo);
res.status(404).send(`Todo with id ${id} not found`);
});
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
Code language: JavaScript (javascript)
Expressルーティングのサンプルソースコードをダウンロードする
まとめ
- エンドポイントとは、クライアントがリソースにアクセスしたり、操作関数を実行したりするために使用できる特定のURL(またはパス)とHTTPメソッドを指します。
- ルートは、アプリケーションが特定のエンドポイントにどのように応答するかを定義します。
- ルートを定義するには、Express appオブジェクトのメソッドを使用します。