Express.js アプリケーション構造解説
Express.js アプリケーションの構造について (日本語)
Express.js は、Node.js のウェブアプリケーションフレームワークです。効率的なアプリケーション開発を支援するために、特定の構造に従うことが推奨されます。以下では、Express.js アプリケーションの一般的な構造について説明します。
プロジェクトディレクトリ
- public: 静的ファイル(CSS、JavaScript、画像)を保存するディレクトリ。
- models: モデルファイル。データベースとのインタラクションを定義します。
- controllers: コントローラーファイル。ビジネスロジックを処理し、ビューやレスポンスを生成します。
- routes: ルーティングに関するファイル。HTTPリクエストを適切なハンドラーにマッピングします。
- app.js: エントリーポイントファイル。アプリケーションの起動とルーティング設定を行います。
app.js ファイルの例
const express = require('express');
const app = express();
const path = require('path');
// 静的ファイルのパスを設定
app.use(express.static(path.join(__dirname, 'public')));
// ルーティング設定
app.use('/', require('./routes/index'));
// ポートの設定とリスニング
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
ルーティングファイル (routes/index.js) の例
const express = require('express');
const router = express.Router();
// GETリクエストへの処理
router.get('/', (req, res) => {
res.render('index', { title: 'Express' });
});
module.exports = router;
ビューファイル (views/index.pug) の例
html
head
title= title
body
h1 Express
重要なポイント
- 静的ファイル: CSS、JavaScript、画像などの静的ファイルを適切に管理します。
- モデル: データベースとのインタラクションを定義します。
- コントローラー: ビジネスロジックを処理し、ビューやレスポンスを生成します。
- ルーティング: HTTPリクエストを適切なハンドラーにマッピングします。
- モジュール化: 各ファイルは特定の機能を担当し、再利用性を高めます。
Express.js アプリケーションの構造コード解説
コード例の詳細解説
先ほどのコード例をより詳しく解説していきます。
app.js
app.listen(port, () => { ... });
: 指定されたポート (デフォルトは 3000) でサーバーを起動します。app.use('/', require('./routes/index'));
: ルート/
に対するリクエストをroutes/index.js
ファイルに委譲します。app.use(express.static(path.join(__dirname, 'public')));
:public
ディレクトリを静的ファイルのルートとして設定します。これにより、ブラウザから直接 CSS、JavaScript、画像ファイルにアクセスできるようになります。const path = require('path');
: Node.js のpath
モジュールをインポートし、ファイルパスを操作するために使用します。const app = express();
: Express アプリケーションを作成します。const express = require('express');
: Express モジュールをインポートします。
routes/index.js
res.render('index', { title: 'Express' });
:index.pug
という名前のビューファイルをレンダリングし、title
変数にExpress
を渡します。router.get('/', (req, res) => { ... });
: GET メソッドで/
にアクセスされた場合に実行される処理を定義します。const router = express.Router();
: Router オブジェクトを作成し、ルーティングの設定を行います。
views/index.pug
h1 Express
: h1 タグで "Express" と表示body
: body セクションtitle= title
: title タグにtitle
変数の値を設定head
: head セクションhtml
: HTML ドキュメントの開始タグ
コードの動作
- リクエスト
ブラウザから/
にアクセスすると、リクエストはapp.js
に到達します。 - ルーティング
app.js
はリクエストをroutes/index.js
に転送します。 - 処理
routes/index.js
はindex.pug
をレンダリングし、HTML を生成します。 - レスポンス
生成された HTML がブラウザに送信され、画面に表示されます。
- 静的ファイル
express.static()
を使用して、静的ファイルを配信します。 - テンプレートエンジン
Pug (または EJS など) を使用して、動的な HTML を生成します。 - ルーティング
app.use()
やrouter.get()
などのメソッドを使って、HTTP メソッドと URL パスを関連付けます。 - MVCパターン
Express.js は MVC (Model-View-Controller) パターンに基づいた構造を採用しています。- Model
データベースとのやり取り (この例では実装されていません) - View
ユーザーインターフェース (pug ファイル) - Controller
ビジネスロジック (routes ファイル)
- Model
この構造は、Express.js アプリケーションの基本的な構成を示しています。より複雑なアプリケーションでは、ミドルウェア、エラー処理、データベース接続などの機能を追加していくことになります。
- データベース
MongoDB、MySQL、PostgreSQL など、様々なデータベースと接続できます。 - テンプレートエンジン
Pug の他にも、EJS、Handlebars など様々なテンプレートエンジンが利用できます。 - ミドルウェア
リクエストとレスポンスの間に挟んで処理を行う関数です。認証、ログ、エラー処理などに利用されます。
より深く学ぶために
- チュートリアル
Qiita や YouTube などには、多くの Express.js のチュートリアルがあります。
従来の構造の復習
代替手法
しかし、全てのケースにおいてこの構造が最適とは限りません。プロジェクトの規模や特性、開発チームのスキルなどに応じて、様々な代替手法が考えられます。
マイクロサービスアーキテクチャ
- デメリット
- 分散システム特有の複雑さがある
- サービス間の通信オーバーヘッドが発生する
- メリット
- スケーラビリティが高い
- 各サービスを独立して開発、デプロイできる
- 技術選択の自由度が高い
- 特徴
アプリケーションを小さな独立したサービスに分割し、各サービスが独自の技術スタックで実装されます。
サーバーレスアーキテクチャ
- デメリット
- コールドスタートの問題がある
- 関数間の連携が複雑になる場合がある
- メリット
- サーバー管理の負担が軽減される
- コスト効率が良い
- 特徴
サーバーの管理をクラウドプロバイダーに任せ、イベント駆動型の関数で処理を実行します。
モノリシックアーキテクチャ
- デメリット
- スケールアウトが難しい
- コードベースが肥大化しやすい
- メリット
- 開発初期段階では迅速に開発できる
- デプロイが簡単
フレームワークの選択
- 考慮点
- コミュニティの規模
- 提供されている機能
- 学習コスト
- Express.js以外
Koa.js, Hapi.jsなど、他のNode.jsフレームワークには独自の構造や特徴があります。
各手法の選択基準
- 開発期間
短期間で開発を完了させる必要がある場合は、モノリシックアーキテクチャが選択肢に入るかもしれません。 - スケーラビリティ
大規模なトラフィックに対応する必要がある場合は、マイクロサービスやサーバーレスアーキテクチャが有効です。 - パフォーマンス要求
高いパフォーマンスが要求される場合は、サーバーレスアーキテクチャが適している場合があります。 - 開発チームのスキル
マイクロサービスやサーバーレスアーキテクチャは、高度な技術力が必要となります。 - プロジェクト規模
小規模なプロジェクトであれば、モノリシックアーキテクチャでも十分な場合もあります。
Express.jsアプリケーションの構造は、プロジェクトの要件に合わせて柔軟に選択することが重要です。一つの手法に固執せず、様々な選択肢を検討し、最適なアーキテクチャを選択しましょう。
- 各フレームワークのドキュメント
Koa.js, Hapi.jsなどの公式ドキュメント - サーバーレスアーキテクチャ
AWS Lambda、Google Cloud Functionsなどのドキュメント - マイクロサービス
Martin Fowlerの「Microservices」
node.js express