Node.js

Express.jsとは?Node.jsバックエンド入門とExpress 5.3の変更点・4系からの移行

Express.jsとは?Node.jsバックエンド入門とExpress 5.3の変更点・4系からの移行

Express.jsはNode.jsでバックエンドを書くときの事実上の標準フレームワークです。ただ、いま調べ物をすると情報の世代がずれています。日本語の解説記事の多くはExpress 4を前提にしていますが、npm install express で入るのはExpress 5で、2026年10月9日には5.3.0が出ました。Content-Typeが合わないときの req.body が {} ではなく undefined になる、app.get('/*') が起動時にエラーになる——記事どおりに書いて動かない原因はたいていこの世代差です。この記事では、Expressが何を肩代わりしているのかをNode.js標準の node:http との差分で押さえ、Express 5.3時点の書き方と4系からの移行点を、手元で実行した結果つきで整理します。

まとめ

  • Express.jsとは:node:http だけでは手書きになるURL分岐(ルーティング)、共通処理の連鎖(ミドルウェア)、ボディのパースや静的ファイル配信、レスポンス生成を引き受ける最小構成のWebフレームワーク。DB接続・認証・バリデーションは同梱しない。
  • 最新版は5.3.0(2026年10月9日)。4系は latest-4 タグの4.22.3(2026年9月14日)。新規開発は5系を選ぶ。
  • 4系のEOLはまだ決まっていない。2025年の計画では「2026年10月1日より前にはしない」とされていたが、2026年10月28日時点の公式サポート表で4.xの終了日は「ongoing」のまま。ただし機能追加は来ない。
  • 移行で最初に踏む地雷は3つ:Content-Typeが合わないときの req.body が {} ではなく undefined、ワイルドカードは /*splat と命名必須、res.send(200) のような数値ステータスの廃止。公式codemodはこのうち /* を書き換えない。
  • async関数のthrowが自動でエラーハンドラへ流れるのがExpress 5最大の実利。express-async-errors は不要になる。
  • Node.jsは18以上が必須だが、18と20はすでにサポート終了。本番はNode.js 24か、2026年10月28日にLTS入りする予定の26を選ぶ。

Express.jsの役割:node:httpとの機能差

Express.jsは2010年にTJ Holowaychukが公開し、現在はOpenJS Foundationのプロジェクトとして開発されているNode.js用のWebフレームワークです。機能を並べるより、Node.jsに最初から入っている node:http で同じものを書いたときに何が残るかを見たほうが、役割を正確につかめます。Node.js自体の仕組みはNode.jsとは?仕組み・版の選び方・標準機能で動かす手順を実装目線で解説で扱っています。

Expressが肩代わりしている処理

node:http でJSONを返すAPIを2本用意すると、こうなります。

import http from 'node:http';

const server = http.createServer((req, res) => {
  const url = new URL(req.url, `http://${req.headers.host}`);

  if (req.method === 'GET' && url.pathname === '/users') {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify([{ id: 1 }]));
    return;
  }
  if (req.method === 'POST' && url.pathname === '/users') {
    let body = '';
    req.on('data', (chunk) => { body += chunk; });
    req.on('end', () => {
      const data = JSON.parse(body);   // 壊れたJSONで例外、サイズ上限も自前
      res.writeHead(201, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify(data));
    });
    return;
  }
  res.writeHead(404).end();
});
server.listen(3000);

メソッドとパスの分岐、ボディのストリーム受信とJSONパース、Content-Typeとステータスコードの手当て、404のフォールバック——アプリ固有のロジックはほとんど無いのに、定型処理で埋まります。ルートが増えるほど、この if の連鎖では分岐の順序や共通処理の重複を管理する負担が増えます。

Expressでは同じものをこう書きます。

import express from 'express';

const app = express();
app.use(express.json());

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

app.post('/users', (req, res) => {
  res.status(201).json(req.body);
});

app.listen(3000);

Expressが引き受けているのは、(1)メソッド+パスによるルーティング、(2)リクエストを順に通す共通処理=ミドルウェア、(3)ボディのパースや静的ファイル配信、(4) res.json() のようなレスポンス生成のショートカットです。データベース接続・認証・バリデーション・ORMは同梱していません。RailsやDjangoのようなフルスタックではなく、必要なものをnpmから選んで足す前提の設計で、この薄さがExpressの性格そのものです。

「Expressを使わない」判断が成り立つ場面

Node.jsには fetch や URL などのWeb標準APIが本体に入っており、素の node:http でも昔ほど苦しくありません。ルートが2〜3本のヘルスチェック用サーバーや、AWS Lambdaのようにルーティングをプラットフォーム側(API Gateway)が持つ構成では、Expressを挟む必然性は薄くなります。

判断基準はルートが増えるか、共通処理(認証・ログ・CORS・エラー整形)を横断的にかけたいかの2つです。どちらかがYesなら、ルーティングとミドルウェアの仕組みを自作せずに済むExpressを第一候補にします。どちらもNoなら node:http のままでかまいません。

Express 5と4の違い:移行前に押さえる破壊的変更

いちばん事故が起きるのがここです。Express 4を前提にした日本語記事も残っていますが、新規インストールで入るのは5系です。

バージョンの現況と4系のサポート期限

npmレジストリの配布タグを2026年10月28日に確認した結果は次のとおりです。

系統 npmタグ 最新版 公開日 Node.js要件
5.x latest 5.3.0 2026-10-09 18以上
4.x latest-4 4.22.3 2026-09-14 0.10以上

Express 5.0.0は2024年9月に公開され、5.1.0が2025年3月31日に latest タグを取得しました。そのときのExpress公式ブログのLTS計画では、4.xは2025年4月1日にMAINTENANCE(セキュリティ修正と優先度の高いバグ修正だけを受ける段階)へ移り、EOLは「2026年10月1日より前にはしない(no sooner than)」とされました。同じ表の注記には「v4は特例で、MAINTENANCEを延長する可能性がある」「目標であって約束ではない」とも書かれています。

実際、その日付を過ぎた2026年10月28日時点でも、公式のVersion Supportページは4.xのサポート終了日を「ongoing」としており、EOLの告知はありません。4.22.3でも依存の qs を6.16系に上げる修正が入っています。とはいえ4系に新機能は来ないので、「まだ切られていない」を理由に移行を先送りするのは得策ではありません。EOLの告知が出てから慌てないよう、移行の段取りは今のうちに組んでおくべきです。

Node.js側は、Node.jsのリリーススケジュールで18と20がすでにEOL(20は2026年4月30日)、22と24はMaintenance LTS(24は2026年10月20日から・2028年4月30日まで)、26は2026年10月28日にActive LTSへ移る予定です。Express 5の下限は18ですが、本番で選ぶのは24か26です。26の変更点はNode.js 26の新機能と破壊的変更・LTS移行日|24からの移行手順【26.11.1対応】、プロジェクトごとの切り替えはNodebrewとは?Node.jsのインストール・切り替え手順と1.2.0の注意点【2026年】で確認できます。

Express 5の破壊的変更:リクエスト・ルート・レスポンス

公式の移行ガイド(Express 5への移行)から、既存コードが実際に動かなくなる変更を抜き出すと次のとおりです。

項目 Express 4 Express 5
パーサ登録済み・Content-Type不一致時の req.body {} undefined
ワイルドカード /* /*splat(命名必須・値は配列)
任意パラメータ /:file.:ext? /:file{.:ext}
数値ステータス送信 res.send(200) 廃止 → res.sendStatus(200)
ボディ+ステータス res.json(obj, 201) 廃止 → res.status(201).json(obj)
リダイレクト res.redirect(url, 301) res.redirect(301, url)(引数順が逆)
req.query 書き換え可 getter(代入不可)
urlencoded の extended 既定 true 既定 false
express.static の dotfiles ドットファイルは無視・ドットディレクトリ内は配信 既定 ignore
削除されたメソッド app.del() app.delete()
削除されたメソッド req.param() req.params / req.query / req.body
削除されたメソッド res.sendfile() res.sendFile()

実務でいちばん多いのは req.body です。Express 4では express.json() を登録していてもContent-Typeが対象外なら req.body は空オブジェクトになり、req.body.name は静かに undefined を返していました。Express 5では req.body 自体が undefined なので、同じコードが TypeError: Cannot read properties of undefined で落ちます。4.22.3と5.3.0で、express.json() を登録した状態に text/plain のボディを送ると、4系は {}、5系は undefined でした。パーサを1つも登録していない場合は、4系でも undefined です。

ルーティング側は、内部のパスマッチャがpath-to-regexp v8に上がった影響です。app.get('/*', handler) は登録した時点で Missing parameter name at index 2: /* という例外を投げ、サーバーが起動しません。app.get('/files/*splat', handler) と定義すると、/files/a/b に対して req.params.splat は ['a', 'b'] の配列になります。正規表現文字を直接埋めていた '/[a|b]/:slug' のような書き方は、パスの配列 ['/a/:slug', '/b/:slug'] に置き換えます。

Express 5で消える定型:async関数のエラー処理

移行の手間に見合う最大の見返りがこれです。Express 4では、非同期ハンドラ内で throw された例外はフレームワークに捕捉されず、プロセスを落とすか、リクエストが応答なしでハングしました。そのため全ハンドラに try/catch を書いて next(err) に渡すか、express-async-errors を当てるのが定石でした。

Express 5は、ハンドラが返した拒否済みPromiseをエラーハンドリングミドルウェアへ自動で転送します。

// Express 5:try/catch も next(err) も不要
app.get('/users/:id', async (req, res) => {
  const user = await db.findUser(req.params.id);   // ここで reject しても
  if (!user) throw new NotFoundError();            // ここで throw しても
  res.json(user);                                  // 下のエラーハンドラへ届く
});

// エラーハンドラは引数4つ(この形でだけエラー用と認識される)
app.use((err, req, res, next) => {
  // 最小例。5xxの文言を隠す本番向けの形は後述
  res.status(err.status ?? 500).json({ message: err.message });
});

エラーハンドラは引数が4つ(err, req, res, next)であることでエラー用と判別されるため、next を使わないからと省略すると通常のミドルウェア扱いになり、エラーを受け取れません。またすべてのルート定義より後ろに置く必要があります。

公式codemodで自動移行できる範囲と残る手作業

Expressチームは移行用のcodemodを公開しています。4系のコード(app.del・res.send(200)・res.redirect('/y', 301)・res.json(obj, 201)・req.param('id')・'/*'・res.sendfile を1ファイルに並べたもの)に対して実行しました。

npx codemod@latest @expressjs/v5-migration-recipe

結果は次のとおりです。

  • app.delete・res.sendStatus(200)・res.redirect(301, '/y')・res.status(201).json(...)・req.params.id・res.sendFile へ書き換わった。ただし、req.param('id') がボディやクエリから値を取得していた場合、req.params.id への変更では動作を維持できない。
  • app.get('/*', ...) はそのまま残った。起動時の例外は手で /*splat に直す必要がある。
  • res.sendFile には { dotfiles: 'allow' } が自動で足された。codemodは「4系の挙動を残す」とコメントを付けるが、'allow' は .env を含むすべてのドットファイルを配信する設定で、4系の既定より広い(express.static を4.22.3で試すと、.env は404、.well-known 内のファイルは200だった)。不要なら消す。
  • package.json の express は ^5.0.0 に上がり、使っていなくても mime-types が依存に追加された。
  • 対象ディレクトリがGit管理下でないと「not tracked by Git」で止まる。差分を確認できる状態で実行する前提の作り。

req.body の undefined 化と urlencoded の extended 既定値は、codemodでも起動時のエラーでも検出されず、実行時に初めて壊れます。手順は、Node.jsを24以上に上げる→codemodを当てて差分を読む→/* を grep で探して命名する→express.json() と express.urlencoded({ extended: true }) を明示する、の順です。着手前に supertest でHTTPレベルのテストを用意しておくと、実行時にしか出ない壊れ方を拾えます(テストランナーはVitest 4の新機能と移行ガイド|最新バージョンは5.0・4.1系の保守と更新手順を参照)。

Express 5.3.0で変わった挙動:5.2系から上げる前の確認点

5.3.0はマイナー版ですが、リリースノートには出力が変わる変更が含まれます。5.2.1と5.3.0で同じコードを動かし、差が出たものを並べます(Node.js 26.5.0で実行)。

コード 5.2.1の出力 5.3.0の出力
res.attachment('user.html') filename="user.html" filename=user.html
Content-Type: text/plain; foo=bar で send charset=utf-8; foo=bar foo=bar; charset=utf-8
既定エラーハンドラのログ スタックのみ [cause] と独自プロパティも出力

ファイル名の引用符が外れるのは content-disposition 2.0系への更新によるもので、RFC 6266上は同じ意味です。壊れるのは、Content-Disposition や Content-Type のヘッダ文字列を完全一致で検証しているテストのほうです。5.3.0に上げてスナップショットテストが落ちたら、まずここを疑ってください。

既定のエラーハンドラがエラーオブジェクト全体を出すようになったため、new Error('...', { cause }) で包んだ原因がログに残ります。ORMの例外が持つ詳細プロパティも出るので、ログ基盤に機微な値が流れていないかは確認が要ります。

セキュリティ面では、依存の body-parser が ^2.3.0 に上がりました。express.json({ limit: 'abc' }) のように不正な limit を渡すと、以前は上限が黙って無効になっていたのが、初期化時に option limit "abc" is invalid で例外を投げます。設定ミスで起動しなくなったら、それは上限が効いていなかった状態が表に出ただけです。req.ip を左右する proxy-addr も2.0.8へ上がっています(後述の「セキュリティ更新の追い方」で説明)。

Expressの使い方:インストールからAPI公開まで

セットアップとサーバー起動

ESM(import)で書くため "type": "module" を指定します。

mkdir my-api && cd my-api
npm init -y
npm pkg set type=module
npm install express        # 5.3.0 が入る(2026年10月時点)
npm install -D nodemon
// app.js
import express from 'express';

const app = express();
const PORT = process.env.PORT ?? 3000;

app.use(express.json());                                  // JSONボディを解釈
app.use(express.urlencoded({ extended: true }));          // フォームのネストを許可
app.use(express.static('public'));                        // public/ を静的配信

app.get('/health', (req, res) => res.json({ status: 'ok' }));

app.listen(PORT, () => console.log(`listening on ${PORT}`));

node app.js で起動し、http://localhost:3000/health が {"status":"ok"} を返せば成功です。開発中は npx nodemon app.js にすると保存のたびに再起動します(Node.js 22以降なら node --watch app.js でも可)。express.static('public') では public/style.css が /style.css で配信され、ディレクトリ名はURLに出ません。

ルーティング:メソッド・パスパラメータ・クエリ

// パスパラメータ: /users/42 → req.params.id === '42'(文字列)
app.get('/users/:id', (req, res) => {
  res.json({ id: Number(req.params.id) });
});

// クエリ文字列: /search?q=node&page=2 → req.query.q, req.query.page
app.get('/search', (req, res) => {
  const { q, page = '1' } = req.query;   // 5系では req.query への代入は不可
  res.json({ q, page: Number(page) });
});

// Express 5のワイルドカード:命名必須・値は配列
app.get('/files/*splat', (req, res) => {
  res.json({ segments: req.params.splat });   // /files/a/b → ['a','b']
});   // /files 自体は404。含めるなら '/files{/*splat}'

req.params.id のような通常の名前付きパラメータは文字列で、ワイルドカードは文字列配列です。通常のパラメータを数値として扱うなら明示的に変換します。ルートが増えたら express.Router() でファイルを分け、app.use('/users', usersRouter) のようにプレフィックスを付けてマウントします。

POSTのJSON・フォームデータ:標準パーサによる受信

古い記事は npm install body-parser から始まりますが、Express 4.16以降、body-parserの機能は本体に取り込まれています。追加インストールは不要で、express.json() と express.urlencoded() をそのまま使います。

app.use(express.json({ limit: '1mb' }));                 // Content-Type: application/json
app.use(express.urlencoded({ extended: true }));         // HTMLフォーム(x-www-form-urlencoded)

app.post('/users', (req, res) => {
  if (!req.body?.name) {                                 // 5系では req.body 自体が undefined になりうる
    return res.status(400).json({ message: 'name is required' });
  }
  res.status(201).json({ id: 1, name: req.body.name });
});

req.body が undefined のままなら、原因はほぼ2つです。express.json() を app.post() より後ろに登録している(ミドルウェアは登録順に実行される)か、クライアントが Content-Type: application/json を送っていないかです。パーサはContent-Typeを見て動くので、ヘッダが無ければ何もしません。ファイルアップロード(multipart/form-data)は本体では扱えず、multer(2026年10月時点で2.5.0)などを足します。

ミドルウェアの仕組み:next()と登録順

ミドルウェアは (req, res, next) を受け取る関数で、登録した順にリクエストを通していきます。next() を呼べば次へ進み、res.json() などで応答すればそこで打ち切られます。next() も応答もしなければ、リクエストは宙吊りになります。ミドルウェアで応答が止まる場合は、まず各分岐でnext()かレスポンス送信に到達しているかを確認します。

// 全リクエストの所要時間をログに出す
app.use((req, res, next) => {
  const start = process.hrtime.bigint();
  res.on('finish', () => {
    const ms = Number(process.hrtime.bigint() - start) / 1e6;
    console.log(`${req.method} ${req.originalUrl} ${res.statusCode} ${ms.toFixed(1)}ms`);
  });
  next();                       // 呼ばないとここで止まる
});

// 特定パスへの適用例:ヘッダの有無だけを確認。実際の認証にはトークンの検証が必要
app.use('/admin', (req, res, next) => {
  if (!req.headers.authorization) return res.status(401).end();
  next();
});

「登録順がすべて」という性質から、配置は決まってきます。ログやCORSのような全体にかけるものを最上段、express.json() などのパーサをルート定義より前、認証を必要なルートの直前、404ハンドラとエラーハンドラを最下段に置きます。

バックエンドフレームワークの選定:Fastify・Hono・NestJSとの使い分け

Express・Fastify・Hono・NestJSの設計思想と適用場面

フレームワーク 設計思想 向く場面
Express 最小構成・自由に組み立てる 一般的なREST API、既存資産と情報量を重視
Fastify JSON Schemaで検証・シリアライズ スキーマ駆動でスループットを詰めたいAPI
Hono Web標準のRequest/Response Cloudflare Workers・Deno・Bunなど複数ランタイム
NestJS DI+デコレータでレイヤを規定 大規模・多人数で構造を揃えたい開発

NestJSはExpressの競合ではなく上位レイヤです。NestJSは既定でExpressをHTTPアダプタとして内部に抱えており、NestJSを選ぶことはExpressを捨てることを意味しません(ValidationPipeなどNestJS側の作法はDTOとは?意味・Entityとの違いとNestJSのValidationPipe設定【v12実測】で扱っています)。逆にHonoはNode.js固有のAPIに依存せずWeb標準のRequest/Responseで組まれているため、エッジランタイムへ載せる前提ならExpressより素直に収まります。HonoのAPIと書き味はHono vs FastAPI(Python)の違い|Honoとは・メリット・使い方を実行結果で比較【Hono 4.13】が詳しいです。

Expressを選ぶべきでない場面

次のどれかに当てはまるなら、Expressは第一候補から外して構いません。

Cloudflare Workersなどのエッジ環境で動かす場合。ExpressはNode.jsの http モジュールに強く依存しており、Web標準APIベースのランタイムでは互換レイヤ頼みになります。最初からHonoで書くほうが摩擦は小さくなります。

複数チームでモノリスを開発し、レイヤ構造とDIの規約を統一したい場合。Expressは構造を一切強制しないため、ディレクトリ構成もDIも各自の裁量になり、規模が増えるほど設計のばらつきが直接コストになります。レイヤ構造とDIを枠組みとして強制するNestJSのほうが、長期の保守は安定します。

リクエスト単価のスループットが要件に直結する場合。Fastifyはレスポンスのシリアライズ自体をJSON Schemaから最適化する設計で、同じJSONを返す用途ではExpressより有利です。ただしDBや外部APIの待ち時間が支配的なアプリでは、フレームワークだけを替えてもレイテンシの改善は限定的です。フレームワークの速さを理由にExpressを避ける前に、ボトルネックが本当にフレームワーク層にあるかを計測してください。DBや外部APIが支配的なら、先にその待ち時間を改善します。

既存の業務システムとExpressで作ったAPIをどうつなぐかまで含めて検討する場合は、弊社のAPI開発・システム連携でも設計から支援しています。

本番運用の初期設定:CORS・エラー処理・TypeScript・セキュリティ更新

CORS(コルス):別オリジンへのレスポンス共有設定

CORS(Cross-Origin Resource Sharing、読み方は「コルス」)は、別オリジンのJavaScriptにレスポンスの読み取りを許可するため、サーバーが応答ヘッダでブラウザに条件を伝える仕組みです。CORS自体はAPIの認証・認可を行いません。ReactやVueの開発サーバー(例:http://localhost:5173)からExpress(http://localhost:3000)を呼ぶと、ブラウザがCORSポリシーでブロックします。ExpressにCORS機能は同梱されていないため、Express公式org(expressjs/cors)が管理するミドルウェアを入れます。プリフライトの仕組みとエラーの読み方はCORSとは?仕組み・プリフライト・サーバー設定例・エラー解決を実装目線で解説で扱っています。

npm install cors
import cors from 'cors';

app.use(cors({
  origin: ['http://localhost:5173', 'https://app.example.com'],   // 許可オリジンを列挙
  credentials: true,                                              // Cookie を送る場合
}));

app.use(cors()) と引数なしで書くと Access-Control-Allow-Origin: * になり、資格情報を含まないリクエストでは、あらゆるオリジンのJavaScriptによるレスポンスの読み取りを許します。認証情報を使わず広く公開するAPIでは本番でも使えます。読み取り元を限定するAPIでは、許可するオリジンを明示してください。credentials: true とワイルドカードのオリジンは仕様上併用できないため、Cookieを使うなら必ずオリジンを列挙します。

404ハンドラとエラーハンドラの最下段配置

// すべてのルート定義の後ろ:どのルートにも当たらなかった場合
app.use((req, res) => {
  res.status(404).json({ message: 'Not Found' });
});

// さらに後ろ:引数4つのエラーハンドラ
app.use((err, req, res, next) => {
  console.error(err);
  if (res.headersSent) return next(err);
  const candidate = err.status ?? err.statusCode;
  const status = Number.isInteger(candidate) && candidate >= 400 && candidate <= 599 ? candidate : 500;
  res.status(status).json({
    message: status < 500 ? err.message : 'Internal Server Error',   // 500の詳細は外に出さない
  });
});

500系のメッセージやスタックトレースをJSONで返すと、内部構造の露出につながります。500以上のエラーとステータスを持たない想定外の例外は固定文言に丸め、詳細はログにだけ残します。レスポンスの送信が始まった後のエラーは next(err) で既定のエラーハンドラに渡し、接続を閉じさせます。

TypeScript対応:@types/expressとRequest拡張

Express本体はJavaScriptで書かれており、型定義は @types/express(2026年10月時点で5.0.6)を別途入れます。

npm install -D typescript @types/express @types/node tsx
import express, { type Request, type Response } from 'express';

const app = express();

app.get('/users/:id', (req: Request, res: Response) => {
  res.json({ id: req.params.id });
});

認証ミドルウェアで req.user のような独自プロパティを生やすと、TypeScriptは「Request に user は存在しない」とエラーを出します。as any で潰さず、宣言のマージで Request 自体を拡張します。

// types/express.d.ts
declare global {
  namespace Express {
    interface Request {
      user?: { id: string; role: string };
    }
  }
}
export {};

このファイルを tsconfig.json の include に含めれば、req.user?.role が型付きで参照できます。

セキュリティ更新の追い方:本体よりミドルウェアの修正が多い

Expressチームは公式ブログでセキュリティリリースをほぼ毎月まとめて告知しています。2026年9月30日の回では、compression・cookies・hbs・morgan・multer・multiparty・proxy-addr の7件が修正されました。Express本体ではなく、周辺のミドルウェアや依存モジュールが対象になる回が大半です。

この回でCriticalとされたのが proxy-addr 2.0.8未満の不具合です。app.set('trust proxy', '::ffff:10.0.0.0/8') のように信頼するプロキシをIPv4射影IPv6表記で書くと、すべての接続元を「信頼できるプロキシ」とみなし、攻撃者が X-Forwarded-For で req.ip を任意の値にできました。IPで絞った管理画面やレート制限が素通りになる種類の不具合です。

運用では次の2つを決めておきます。

  • package-lock.json がある状態で npm update express compression multer のように使っているミドルウェア名を並べて更新し、npm ls proxy-addr で推移的依存の版まで確認する。
  • trust proxy は true ではなく、実際に前段にいるロードバランサのアドレスで指定する。ホップ数を指定する場合は、設定値より短い経路でクライアントが到達できないことを確認する。

なお、Node.js本体の脆弱性は別系統で告知されます。影響の確認方法はNode.jsの脆弱性とは|影響の確認方法と対応バージョン・アップデート手順【2026年10月最新】にまとめています。

よくある質問(FAQ)

Express.jsとNode.jsの違いは?

Node.jsはJavaScriptの実行環境(ランタイム)で、Express.jsはNode.js上で動くWebフレームワークです。Node.jsだけでもサーバーは書けますが(標準の node:http)、ルーティングやボディのパースを自前で組むことになります。ExpressはNode.jsを置き換えるものではなく、その定型部分を引き受けるライブラリです。

ExpressとReactの違いは?

動く場所が違います。Reactはブラウザで画面を組み立てるフロントエンドのUIライブラリで、ExpressはサーバーでHTTPリクエストを受けて応答するバックエンドのフレームワークです。両者は競合せず、ReactのアプリがExpressで作ったAPIをfetchで呼ぶ組み合わせが典型です。その際、オリジンが違えばExpress側にCORSの設定が要ります。

Express 4と5のどちらを使うべき?

新規開発は5系です。npm install express で入るのは5系(2026年10月時点で5.3.0)です。4系は4.22.3まで保守が続いていますが、2025年4月からセキュリティ修正と重大なバグ修正だけの段階にあり、EOLの日付は2026年10月28日時点で未発表です。既存の4系アプリも、Node.jsを24以上に上げたうえで移行を計画してください。

body-parserはインストールが必要?

不要です。Express 4.16以降、JSONとURLエンコードのパーサは本体に入っており、express.json() と express.urlencoded() で足ります。npm install body-parser から始まる解説はそれ以前の情報です。ファイルアップロード(multipart/form-data)だけは本体で扱えず、multer などが要ります。

req.bodyがundefinedになるのはなぜ?

Express 5では、パーサが処理しなかったリクエストの req.body は、4系の {} ではなく undefined です。express.json() を登録していない、ルート定義より後ろに登録している、リクエストに Content-Type: application/json が付いていない、のいずれかを疑ってください。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.29 テックブログ ソニー生命の不正アクセス:38.5万件の対象確認と窓口、停止中の手続き
  2. 2026.10.31 テックブログ 無印良品の情報漏洩:MUJIアプリ最大2,726万件の対象確認となりすましメール対策
  3. 2026.10.31 テックブログ 松屋の不正アクセス:237万件の対象確認と窓口、漏れたパスワードの守り方
  4. 2026.10.27 テックブログ Joshin(ジョーシン)不正アクセス:最大600万件の対象とサブスク初期パスワードの対処
  5. 2026.01.30 コラム 税務調査は個人と法人で何が違う?担当部署・件数・調べられる点と追徴税額を比較【令和6事務年度】

RELATED POSTS 関連記事

目次