Express
Express とは
Node.js のフレームワークで、サーバーや API を作成するのに使われます。フロントエンドは持たず、サーバーサイドでのリクエスト・レスポンスの処理が得意です。
サーバーサイドの JavaScript 実行環境の Node.js の開発をスピードアップし、安全にサーバーの作成を行えるのフレームワーク。
Node.js 自体はサーバーサイド JavaScript の実行環境で、HTTP サーバーの作成もできますが、ルーティングやリクエスト処理などを自分で全部書くのは大変です。そこに登場するのが Express で、Node.js でのサーバー構築が圧倒的に楽になり、開発効率が向上します。
Express 自体は Web サーバーとして HTTP リクエストを扱う最低限の機能しかありません。
このフレームワークには、HTTP リクエストとレスポンス、ルーティング、およびミドルウェアといった、大規模なエンタープライズ対応アプリケーションの構築とデプロイのための機能が豊富に盛り込まれています。
ミドルウェアはリクエストとレスポンスの流れの中で特定の処理を追加するための関数として定義されています。Express のミドルウェアは、リクエストがサーバーに到達してから最終的なレスポンスを返すまでの間に、複数の関数を通過させる仕組みで動作します。
開発者には DRY(Don’t Repeat Yourself)の原則に従うことを強制しています。
DRY の原則とは、ソフトウェアパターンの繰り返しを減らし、抽象化で置き換えたり、データの正規化を使って冗長性を避けたりすることを目的としています。
ルーティング
アプリケーションが特定のエンドポイントに対するクライアント要求に応答する方法として、URI (またはパス) と特定の HTTP 要求メソッド (GET、POST など) を決定することです。
各ルートには、1 つ以上のハンドラー関数があり、それらはルートが一致したときに実行されます。
ルート定義では、次の構造を使用します。
app.METHOD(PATH, HANDLER);
- は、
app
のインスタンスです。express
- は、HTTP 要求メソッド です。
METHOD
- は、サーバー上のパスです。
PATH
- は、ルートが一致したときに実行される関数です。
HANDLER
構成と機能
ルーティングやミドルウェアなどの構成は自由度が高く、開発者が設定する必要があります。ファイルベースのルーティングはなく、API のエンドポイントやレスポンス形式もカスタマイズ性が高いです。
ミドルウェアとは
単なる関数のこと。
リクエストからレスポンスの間に実行できる関数のこと。
app.use((req, res, next), => { res.send("hello"); })
何に使われるのか
Express.js は、JavaScript/Node.js のエコシステムにおいて、アプリケーション、API エンドポイント、ルーティングシステム、フレームワークなど、多岐にわたる用途で活用されています。
Express.js で構築できるアプリケーションには、以下のようなものがあります:
シングルページアプリケーション
シングルページアプリケーション(SPA)は、アプリケーション全体が単一のインデックスページにルーティングされる現代的な構成のアプリケーションです。Express.js は、SPA を接続し、一貫したデータ配信を行う API の構築に適したフレームワークです。Gmail、Google Maps、Airbnb、Netflix、Pinterest、PayPal などが SPA の例として挙げられます。これらの企業は、柔軟でスケーラブルなユーザー体験の構築に SPA を採用しています。
リアルタイムコラボレーションツール
Express.js を使用すれば、コラボレーションを促進するリアルタイム型ネットワーキングアプリケーションを容易に開発できます。
また、Express.js はチャットやダッシュボードアプリケーションなどのリアルタイムアプリケーションの開発にも適しており、WebSocket をフレームワークに簡単に統合できます。
Express.js がルーティングとミドルウェアの処理を担当するため、開発者はライブコラボレーションツールの開発においてビジネスロジックに集中できます。
ストリーミングアプリケーション
Netflix のようなリアルタイムストリーミングアプリケーションは複雑で、多層のデータストリームを扱います。このようなアプリを開発するには、非同期データストリームを効率的に処理できる堅牢なフレームワークが必要です。
Express.js は、エンタープライズ向けでスケーラブルなストリーミングアプリケーションの構築とデプロイに最適なフレームワークです。
フィンテックアプリケーション
フィンテックとは、銀行業務や金融サービスをサポートまたは実現するコンピュータプログラムやその他のテクノロジーを指します。フィンテックアプリケーションの開発は現代の業界トレンドであり、Express.js は拡張性の高いフィンテックアプリケーションの構築に適しています。
大規模なユーザー基盤と高いトランザクション量を持つフィンテックアプリケーションの開発を検討している場合、PayPalや Capital One などの企業に倣い、Express.js を活用してアプリケーションを開発することが賢明でしょう。
基本的な仕組み
Express の基本はミドルウェアの積み重ねで、各ミドルウェアは原則的に 3 つの引数を持つ。
- res
- req
- next
流れ
- クライアントからのリクエストが Express のサーバーに送信される
- Express はその内容を解析して決まった形式のオブジェクトに展開
- レスポンスでクライアントに情報を送信
エラーハンドリング
テスト
API
- GET メソッドに対応するハンドラを指定。
app.get("/users/:user_id", (req, res) => { res.send(`Get user ${req.params.user_id}.\n`); });
- リクエストからレスポンスの間に処理する関数などを指定。path が記述されていると指定された path でのみ実行される。path が未記述だと、全ての path で実行される。
app.use(path, (req, res, next) => {});
- 静的ファイルが格納されているフォルダを設定。
app.use(express.static(__dirname + "/public")
ライブラリ
Passport
Passport が管理するのはセッションを利用したユーザー認証の仕組み。
helmet
Router
Express の Routerは、Express フレームワークでアプリケーションのルート(URL や HTTP メソッド)を整理するために提供される機能です。複数のルートを分割し、モジュール化して管理しやすくする役割を果たします。
大きなアプリケーションでは、すべてのルートを 1 つのファイル(例えば
app.js
Router
主な特徴
- ミニアプリケーションのようなもの
は小さな Express アプリケーションのように動作します。独自のミドルウェアやルートを設定し、後でメインアプリケーションに統合できます。
Router
- コードの整理 機能ごとにルートをファイルやモジュールに分割して管理できます。
使用例
以下は、
Router
1. users.js
にルートを定義
users.js
const express = require("express"); const router = express.Router(); // ユーザー一覧を取得するルート router.get("/", (req, res) => { res.send("ユーザー一覧"); }); // ユーザーを追加するルート router.post("/", (req, res) => { res.send("ユーザーを追加しました"); }); // 特定のユーザーを取得するルート router.get("/:id", (req, res) => { res.send(`ユーザーID: ${req.params.id}`); }); module.exports = router;
2. メインアプリケーションで統合
app.js
users.js
const express = require("express"); const app = express(); const userRouter = require("./users"); // 先ほど作成したルートをインポート // "users"に関連するルートを "/users" にマウント app.use("/users", userRouter); app.listen(3000, () => { console.log("Server is running on http://localhost:3000"); });
この場合、以下の URL が有効になります:
- → ユーザー一覧
GET /users
- → ユーザー追加
POST /users
- → 特定のユーザー
GET /users/:id
Router
を使うメリット
Router
- ルートのモジュール化: 各機能やエンドポイントごとにファイルを分けられるため、管理が容易。
- 再利用性: 異なるプロジェクトで簡単に再利用可能。
- 可読性向上: 大規模なアプリケーションでもコードが見やすくなる。
もし、具体的な例や応用的な使い方について質問があれば教えてください!