Node.jsでREST APIを構築するメリット
Node.jsはJavaScriptランタイムであり、フロントエンドエンジニアがバックエンド開発に参入しやすい環境を提供しています。Non-blockingのI/O処理モデルにより、APIサーバーとして高い同時接続性能を発揮します。
| メリット | 説明 |
|---|---|
| フルスタック開発 | JavaScript/TypeScript 一本でフロント〜バックを統一 |
| 豊富なエコシステム | npm/yarn のパッケージが非常に多い |
| 成熟した学習リソース | 書籍・記事・チュートリアルが充実 |
| WebSocket 統合 | リアルタイム機能との統合が容易 |
2025年のNode.js REST API開発では、型安全性と開発体験を重視してTypeScriptでの実装が標準になっています。本記事では、TypeScript + FastifyまたはExpressを使ったREST API構築の実践的な手順を解説します。
プロジェクト構成とディレクトリ設計
実務レベルのREST APIプロジェクトの構成を紹介します。
| ディレクトリ | 役割 |
|---|---|
| routes/ | ルーターの定義 |
| controllers/ | リクエスト処理のロジック(薄く保つ) |
| services/ | ビジネスロジック(テスト容易性の中心) |
| repositories/ | DB アクセス層(ORM 呼び出し) |
| models/ | データモデル・型定義 |
| middlewares/ | 認証・ロギング・Rate Limit 等 |
| validators/ | Zod 等のスキーマ定義 |
| utils/, config/ | ユーティリティ関数・環境変数管理 |
この3層アーキテクチャ(Controller → Service → Repository)により、責任の分離・テスタビリティ・保守性が高まります。
ルーティング・コントローラーの実装
TypeScript + Expressでの実践的なルーティング実装パターンを解説します。
Express Router基本パターン:
usersRouter.get('/:id', async (req, res) => { ... })
usersRouter.post('/', validate(createUserSchema), async (req, res) => { ... })
usersRouter.put('/:id', auth, validate(updateUserSchema), async (req, res) => { ... })
usersRouter.delete('/:id', auth, async (req, res) => { ... })
| 項目 | Express | Fastify |
|---|---|---|
| 速度 | 標準 | Express の 2〜10 倍(ベンチ比) |
| スキーマ統合 | 外部ライブラリ | JSON Schema / Zod 統合・シリアライゼーション最適化 |
| TS型推論 | 外部型定義に依存 | 本体で型推論が優秀 |
| エコシステム | 最大級・情報量豊富 | 急成長中・プラグインで拡張 |
| 向くプロジェクト | 学習・既存資産活用 | 新規・高性能本番API |
認証の実装|JWT・Cookie・セッション
REST APIの認証実装の選択肢と実践的な実装方法を解説します。
| Step | 処理 |
|---|---|
| 1 | POST /auth/login でメール・パスワード検証 |
| 2 | Access Token(短期限)+ Refresh Token(長期限)発行 |
| 3 | 以降の API リクエストに Authorization: Bearer [token] 付与 |
| 4 | Access Token 期限切れ時に Refresh Token で再発行 |
JWT実装時の注意点:
・Refresh TokenはHttpOnly Cookieで保存(XSS対策)
・Access Tokenの有効期限は15分〜1時間が推奨
・本番環境ではRS256(非対称鍵)を使う
バリデーション・エラーハンドリング・ロギング
実務レベルのAPIで必須のバリデーション・エラー処理・ロギングの実装を解説します。
Zodによるバリデーション:
Zodはランタイムのバリデーションと型推論を同時に提供します。リクエストボディ・クエリパラメーター・パスパラメーターのバリデーションに使えます。バリデーションエラー時は400ステータスと分かりやすいエラーメッセージを返します。
グローバルエラーハンドリング:
Expressではerror handling middlewareを最後に追加することで、全ルートで発生したエラーを統一的に処理できます。カスタムエラークラスを使うことで、エラーの種類ごとに適切なHTTPステータスコードを返すことができます。
ロギング(Pinoの使用):
PinoはNode.js向けの高速な構造化ロガーです。JSON形式でのログ出力・リクエストID・ログレベル(error・warn・info・debug)を適切に設定することで、本番環境での問題調査が容易になります。