3.

Node.js Express 入門 — ルーティング / ミドルウェア / 競合 Fastify との比較

編集
この記事の要点
  • Express は Node.js で最も使われている Web フレームワーク。最小構成・薄いラッパー
  • インストール: npm install express、Hello World は 5 行で書ける
  • ルーティング: app.get("/users", handler) / app.post() / app.put() / app.delete()
  • ミドルウェア: app.use(...) で全リクエストに介入。ロギング・認証・ボディパーサーなど
  • req / res オブジェクトに req.params req.query req.body res.json() など
  • 競合: Fastify(高速)/ Koa(async/await ネイティブ)/ NestJS(フルスタック・TS)

Express とは

Express (Express.js) は Node.js 上で動く最小主義の Web アプリケーションフレームワーク。2010 年に TJ Holowaychuk が公開し、現在は OpenJS Foundation 配下のプロジェクトです。npm で最もダウンロードされている Web フレームワークで、Node.js の Web 開発のデファクトスタンダードとなっています。

機能は「ルーティング + ミドルウェア + テンプレートエンジン連携」と最小限。ORM やバリデーション、認証は別ライブラリと組み合わせて使う設計です。

インストールと Hello World

# プロジェクト初期化
mkdir my-app && cd my-app
npm init -y
npm install express

# アプリ作成
cat > app.js <<'EOF'
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello Express!');
});

app.listen(3000, () => {
  console.log('http://localhost:3000');
});
EOF

# 起動
node app.js

5 行で動作する HTTP サーバーが立ち上がります。ブラウザで http://localhost:3000 にアクセスすると "Hello Express!" が表示されます。

ルーティング

const express = require('express');
const app = express();

app.use(express.json()); // JSON body parser

// GET /users
app.get('/users', (req, res) => {
  res.json([{ id: 1, name: 'Alice' }]);
});

// GET /users/:id  (パスパラメータ)
app.get('/users/:id', (req, res) => {
  const id = req.params.id;
  res.json({ id, name: 'Alice' });
});

// POST /users  (JSON body)
app.post('/users', (req, res) => {
  const { name, email } = req.body;
  // ... DB 保存処理
  res.status(201).json({ id: 99, name, email });
});

// PUT /users/:id
app.put('/users/:id', (req, res) => {
  res.json({ updated: true });
});

// DELETE /users/:id
app.delete('/users/:id', (req, res) => {
  res.status(204).send();
});

// Router でグループ化
const router = express.Router();
router.get('/', (req, res) => res.send('list'));
router.get('/:id', (req, res) => res.send('detail'));
app.use('/api/posts', router);
// → /api/posts, /api/posts/:id

app.listen(3000);

ミドルウェア

Express の心臓部。リクエストが届いてからレスポンスを返すまでの処理パイプラインを構成する関数です。

const express = require('express');
const app = express();

// グローバルミドルウェア (全リクエストに適用)
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next(); // 次のミドルウェアへ
});

// 組み込みミドルウェア
app.use(express.json());                    // JSON body
app.use(express.urlencoded({ extended: true })); // form body
app.use(express.static('public'));          // 静的ファイル

// 3rd party
const morgan = require('morgan');
const cors = require('cors');
app.use(morgan('combined'));   // アクセスログ
app.use(cors());               // CORS 許可

// 認証ミドルウェア (個別ルートに)
function requireAuth(req, res, next) {
  const token = req.headers.authorization;
  if (!token) return res.status(401).json({ error: 'no token' });
  // 検証...
  req.user = { id: 1 };
  next();
}

app.get('/me', requireAuth, (req, res) => {
  res.json(req.user);
});

// エラーハンドリングミドルウェア (引数 4 つで判別される)
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: err.message });
});

req / res オブジェクト

プロパティ/メソッド用途
req.paramsURL パスパラメータ /users/:idid
req.queryクエリ文字列 ?page=2&limit=10
req.bodyリクエストボディ (要 express.json() 等)
req.headersHTTP ヘッダー
req.cookiesCookie (要 cookie-parser)
res.send(data)レスポンス送信(文字列 / Buffer / オブジェクト)
res.json(obj)JSON で返す(Content-Type 自動設定)
res.status(code)ステータスコード設定(チェーン可)
res.redirect(url)リダイレクト
res.sendFile(path)ファイル送信

静的ファイル配信

// public/ ディレクトリの中身をそのまま配信
app.use(express.static('public'));
// → public/index.html  →  http://localhost:3000/
// → public/css/main.css → http://localhost:3000/css/main.css

// プレフィックス付き
app.use('/assets', express.static('public'));
// → public/logo.png → http://localhost:3000/assets/logo.png

// 複数ディレクトリ
app.use(express.static('public'));
app.use(express.static('uploads'));

Express Generator

雛形を一発生成する CLI ツール。MVC 風のディレクトリ構成が出てきます。

npx express-generator --view=pug my-app
cd my-app
npm install
DEBUG=my-app:* npm start

# 生成される構造
# my-app/
# ├── app.js
# ├── bin/www
# ├── package.json
# ├── public/
# ├── routes/
# │   ├── index.js
# │   └── users.js
# └── views/
#     ├── index.pug
#     └── layout.pug

エラーハンドリング

// 同期エラーは自動キャッチされる
app.get('/sync-error', (req, res) => {
  throw new Error('boom'); // → エラーハンドラへ
});

// 非同期 (async) は明示的に next(err) が必要
app.get('/async-error', async (req, res, next) => {
  try {
    await someAsyncOp();
    res.send('ok');
  } catch (err) {
    next(err); // ★ 重要
  }
});

// Express 5 系 では async エラーも自動キャッチされる予定

// 404 ハンドラ (最後に置く)
app.use((req, res) => {
  res.status(404).json({ error: 'Not Found' });
});

// エラーハンドリングミドルウェア (最後に置く)
app.use((err, req, res, next) => {
  console.error(err);
  res.status(err.status || 500).json({
    error: err.message,
    stack: process.env.NODE_ENV === 'production' ? undefined : err.stack
  });
});

競合フレームワークとの比較

フレームワーク特徴パフォーマンス選ぶ理由
Express最小構成 / 巨大エコシステム標準情報が一番多い・無難
Fastify高速 / スキーマベースExpress の約 2 倍性能重視 / TypeScript 親和性
KoaExpress 作者の後継 / async/await ネイティブExpress とほぼ同等モダンな API 設計が好み
NestJSAngular 風 / DI / TS 前提内部は Express or Fastify大規模・チーム開発 / 構造化
Hono超軽量 / エッジ動作非常に高速Cloudflare Workers / Bun / Deno

FAQ

Q: Express と Next.js は競合か
A: 違います。Next.js は React のサーバーレンダリングフレームワーク、Express は汎用 Web サーバー。Next.js の API Routes が API 用途を吸収してきていますが、独立した API サーバーには Express が一般的です。

Q: Express 5 はいつ安定版になるか
A: 2024 年に正式版がリリースされました。async エラー自動キャッチや path-to-regexp の更新が主な変更点。既存 Express 4 から大半は互換です。

Q: TypeScript で使うには
A: npm install -D typescript @types/express @types/node ts-nodetsconfig.json を作って ts-node app.ts で起動できます。

編集
Post Share
子ページ
  1. インストール方法
  2. サーバーの起動
同階層のページ
  1. Vue.js
  2. React
  3. Express