12k
All articles

2026年版 Node.js API ベストプラクティス

Zod・Helmet・Pino・グレースフルシャットダウンを用いた Node.js API パターンで、堅牢な本番サービスを構築する手法を解説する。

OpenReplay Team
OpenReplay Team
2026年版 Node.js API ベストプラクティス

Node.jsでAPIを構築することは、本番環境で最初のインシデントが発生するまでは簡単に思えます。バリデーションの欠如がサーバーをクラッシュさせます。未処理のPromise拒否がプロセス全体をダウンさせます。依存関係の脆弱性がユーザーデータを露出させます。

これらの問題には共通の根本原因があります。経験豊富なチームが譲れないものとして扱う基礎的なプラクティスを省略していることです。本ガイドでは、本番システムにおいて重要なNode.js APIのベストプラクティスを取り上げます。これらは、どのフレームワークを選択しても変わらない安定したパターンです。

重要なポイント

  • コードをテスト可能で保守しやすくするため、ルーティング、ビジネスロジック、データアクセスを分離する
  • ZodやAJVなどのスキーマライブラリを使用して、境界ですべての受信データを検証する
  • カスタムエラークラスと適切なロギングを使用した集中型エラーハンドリングを実装する
  • HTTPヘッダー、レート制限、入力サニタイゼーション、依存関係の監査を含むセキュリティ対策を多層化する
  • 本番環境での効果的なデバッグのため、相関IDを含む構造化ロギングを使用する

プロジェクト構造とコード組織化

現代のNode.js APIは、ルーティング、ビジネスロジック、データアクセスの明確な分離から恩恵を受けます。これは特定のパターンを盲目的に従うことではなく、コードをテスト可能で保守しやすくすることが目的です。

実用的な構造は関心事を分離します:

src/
  routes/        # HTTP layer only
  services/      # Business logic
  repositories/  # Data access
  middleware/    # Cross-cutting concerns

ルートハンドラーは薄く保ちます。リクエストを解析し、サービスを呼び出し、レスポンスをフォーマットするだけにすべきです。ビジネスルールは、HTTPのオーバーヘッドなしでテストできるサービス層に配置します。

可能な限りプラットフォームネイティブの機能を優先します。例えば、Node.jsには現在、外部HTTPリクエスト用の組み込みfetch APIが含まれており、多くの場合でサードパーティクライアントの必要性を減らしています。

リクエスト検証とスキーマ強制

受信データを決して信頼しないでください。ZodAJVなどのスキーマ検証ライブラリを使用して、処理前にリクエストボディ、クエリパラメータ、パスパラメータを検証します。

早期に検証し、即座に失敗させます。内部の詳細を公開せずに、API利用者がリクエストを修正するのに役立つ明確なエラーメッセージを返します。

// Validate at the boundary
const createUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1).max(100)
})

スキーマ検証は、生きたドキュメントとしても機能し、自動的なOpenAPI生成を可能にします。

集中型エラーハンドリング

散在するtry-catchブロックは、一貫性のないエラーレスポンスを生成し、バグを隠します。すべてのエラーをキャッチし、一貫してフォーマットする集中型エラーハンドリングミドルウェアを実装します。

適切なHTTPステータスコードを持つカスタムエラークラスを作成します。リクエストID、ユーザーID、操作名などのコンテキストを含めてエラーをログに記録しますが、スタックトレースや内部の詳細をクライアントに公開しないでください。

プロセスレベルのエラーを意図的に処理します。unhandledRejectionuncaughtExceptionを致命的なものとして扱い、コンテキストと共にログに記録し、未定義の状態で継続するのではなく、グレースフルにシャットダウンします。

セキュリティの基礎

セキュリティには複数の層が必要です:

HTTPヘッダー: Helmetを使用するか、手動でヘッダーを設定します—Content-Security-Policy、Strict-Transport-Security、X-Content-Type-Options。

レート制限: エンドポイントを悪用から保護します。認証エンドポイントにはより厳格な制限を適用します。

入力サニタイゼーション: 検証は構造をチェックし、サニタイゼーションは危険なコンテンツを削除します。両方が必要です。

依存関係の衛生管理: CIパイプラインでnpm auditを実行します。ロックファイルを使用します。サプライチェーンリスク検出のためにSocketなどのツールを検討してください。

シークレット管理: シークレットをコミットしないでください。環境変数を使用し、本番環境では専用のシークレットマネージャーを検討してください。

構造化ロギングと可観測性

ログは本番環境における主要なデバッグツールです。Pinoなどのライブラリを使用した構造化ロギング—クエリと集約が可能なJSONログを使用します。

すべてのログエントリに相関IDを含めます。リクエストごとに一意のIDを生成し、呼び出しチェーン全体を通じて渡します。何かが失敗したとき、完全なリクエストパスをトレースできます。

データベース接続と重要な依存関係を検証するヘルスチェックエンドポイントを追加します。これにより、ロードバランサーとオーケストレーターが正しくトラフィックをルーティングできます。

パフォーマンスパターン

ページネーション: 無制限の結果セットを決して返さないでください。合理的なデフォルトと最大制限を持つカーソルベースまたはオフセットページネーションを実装します。

圧縮: ミドルウェア経由またはエッジ(例:リバースプロキシやCDN)でJSONペイロードのレスポンス圧縮を有効にします。

コネクションプーリング: データベース接続はコストがかかります。プールを適切に設定し、枯渇を監視します。

グレースフルシャットダウン: SIGTERMシグナルを処理します。新しいリクエストの受け入れを停止し、実行中の作業を完了し、データベース接続を閉じてから終了します。これにより、デプロイ中のリクエストのドロップを防ぎます。

API設計の一貫性

一貫性のあるAPIは統合の摩擦を減らします:

  • リソースには名詞を、アクションにはHTTPメソッドを使用する
  • 適切なステータスコードを返す(作成には201、削除には204)
  • 初日からAPIをバージョン管理する—URLプレフィックスで十分機能する
  • レスポンスエンベロープとエラーフォーマットを標準化する

OpenAPIでAPIをドキュメント化します。可能な限りスキーマからドキュメントを自動生成します。

テスト戦略

複数のレベルでテストします。ユニットテストはビジネスロジックを分離して検証します。統合テストは、実際のデータベースと依存関係でAPIが正しく動作することを検証します。

HTTP レベルのテストにはSupertestなどのツールを使用します。ハッピーパスだけでなく、エラーパスもテストします—無効な入力、存在しないリソース、認可の失敗など。

まとめ

ここで取り上げたプラクティスは流行りのものではなく、基礎的なものです。検証、エラーハンドリング、セキュリティ、ロギング、一貫した設計は、あらゆる本番APIのバックボーンを形成します。

これらの基礎から始めてください。特定の問題を解決する必要がある場合にのみ複雑さを追加してください。最良のNode.jsプラクティスとは、チームが実際に一貫して従うことができるものです。

よくある質問

Node.js APIにはExpress、Fastify、または他のフレームワークを使用すべきですか?

フレームワークは、ベストプラクティスの一貫した適用よりも重要ではありません。Expressは最大のエコシステムとコミュニティサポートを持っています。Fastifyは初期状態でより優れたパフォーマンスを提供します。どちらも本番APIで十分に機能します。チームの習熟度と特定のパフォーマンス要件に基づいて選択し、選択に関係なく本ガイドのパターンを適用してください。

Node.js APIで認証をどのように処理すべきですか?

独自の認証を実装するのではなく、確立されたライブラリを使用してください。Passport.jsはセッションベースの認証で引き続き人気があります。トークンベースの認証には、JWT検証ミドルウェアを実装します。パスワードはbcryptまたはargon2で保存します。すべてのリクエストでトークンを常に検証し、トークンの有効期限を実装し、長期間有効なセッションにはリフレッシュトークンのローテーションを検討してください。

Node.jsでデータベース接続を処理する最良の方法は何ですか?

リクエストごとに新しい接続を作成するオーバーヘッドを避けるため、コネクションプーリングを使用してください。Prisma、Knex、またはネイティブPostgreSQLドライバーなど、ほとんどのデータベースドライバーとORMはプーリングをサポートしています。データベースの制限と予想される同時実行性に基づいてプールサイズを設定します。接続の枯渇を監視し、グレースフルシャットダウン中に適切なクリーンアップを実装してください。

APIでエラーレスポンスをどのように構造化すべきですか?

すべてのエンドポイントで一貫したエラーレスポンスフォーマットを使用してください。エラーコード、人間が読めるメッセージ、および検証エラー用のオプションの詳細フィールドを含めます。内部エラーを適切なHTTPステータスコードにマッピングします。スタックトレースや内部実装の詳細をクライアントに公開しないでください。デバッグのため、完全なエラーコンテキストをサーバー側でログに記録します。

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.