代表的な面接トピック

バックエンド面接:APIはどのような場合に 204 No Content を返すべきか?

バックエンド普通
Offer.cc 編集チーム公開日 更新日

質問

REST API を設計する際、204、200 空コレクション、または 404 をそれぞれどのような場合に返すべきですか?メソッドのセマンティクス、ボディのルール、互換性、およびコントラクトテストについて説明してください。

プロンプトと適用範囲

REST API の空レスポンスのコントラクトを設計します。削除が成功した場合、どのように応答すべきでしょうか?一致するデータがないコレクションクエリは 204 を返すべきでしょうか?表現を返す必要がない場合、更新が成功した際には何を返すべきでしょうか?存在しないリソース、表現を伴わない成功した操作、非同期操作、および有効な空のコレクションを区別してください。複数の言語で生成されたクライアントが存在し、長期間維持されるコントラクトであることを前提とします。

面接官がテストしていること

ステータスコードを「データがない」ことのショートカットとしてではなく、リソースのセマンティクスとして扱えているかを評価します。204 はメッセージコンテンツを伴わない成功を意味し、メッセージボディを含めてはなりません。200 は [] などの安定した表現を返すことができます。404 はターゲットリソースが存在しないか、現在の表現を持たないことを意味します。DELETE の冪等性、キャッシュ、SDK のデコード処理、および OpenAPI ドキュメントについて論述してください。

回答前の明確化事項

  1. ターゲットは何ですか?単一リソースの削除、単一リソースの更新、およびコレクションのクエリではセマンティクスが異なります。
  2. 空のコレクションは通常の結果ですか?その場合、[] を含む 200 の方が、通常 204 よりも安定したレスポンス型を維持できます。
  3. クライアントは単一の JSON 構造をデコードする必要がありますか?常にボディを読み取る自動生成クライアントは、明示的な分岐がない限り 204 を予期せぬ EOF として処理してしまう可能性があります。
  4. 成功時に新しい表現、ETag、または非同期ジョブ ID が必要ですか?必要な場合は、レスポンスボディを維持し、200、201、または 202 を選択します。

推奨される決定と根拠

操作と表現の必要性に基づいてコントラクトを定義します:

  • 返すべき表現がない成功した DELETE /users/42 は 204 を使用できます。繰り返しの削除が冪等な成功として定義されている場合は、204 のままでも構いませんが、それを文書化してください。
  • GET /users?team=none がメンバーの存在しない既存のコレクションを見つけた場合は、リストの型を維持するために 200 と [] を返します。0 件のレコードは「リソースの欠落」ではありません。
  • GET /users/42 がターゲットを見つけられない場合は 404 を返します。これはターゲットリソースのセマンティクスであり、空リストのセマンティクスではありません。
  • PUT /users/42 が成功し、クライアントが新しい表現を必要とする場合は、JSON を含む 200 を返します。表現が不要な場合は 204 が有効であり、ETag は引き続きメタデータを伝達できます。
  • リクエストは受理されたものの処理が継続している場合は、204 に偽装するのではなく、タスクステータスへのリンクとともに 202 を返します。
http
HTTP/1.1 204 No Content
ETag: "user-42-v7"
Cache-Control: no-store

HTTP/1.1 200 OK
Content-Type: application/json

[]

RFC 9110 では 204 をメッセージコンテンツを持たないものと定義しているため、クライアント、プロキシ、およびテストはボディが存在しないことをコントラクトの一部として扱う必要があります。統一感を持たせるためだけに成功を示す 200 の内部にビジネスエラーを含めたり、わずか数バイトを節約するためだけにすべての空結果を 204 に変更したりしてはなりません。

代替案とトレードオフ

空配列の 200 は型を安定させ、生成された SDK にとって扱いやすく、ページネーションのメタデータを含めることができますが、数バイトのコストがかかります。204 は表現を伴わない成功を明確に表現し、DELETE やデータをエコーバックしない更新に適しています。ただし、クライアントはボディが存在しないケースを処理する必要があり、そこにエラーの詳細を読み取ることはできません。404 は、有効な空コレクションではなく、欠落しているターゲットリソースのために確保してください。

障害モード、境界条件、および反例

  • 空の GET リストに対して 204 を返すと、クライアントは有効な空結果を別のレスポンス型として扱い、ページネーションや汎用デコード処理が破損します。
  • 204 とともに JSON ボディを送信すると、メッセージセマンティクスに違反します。プロキシによって破棄される可能性があり、クライアントの挙動が乖離します。
  • 冪等性を文書化せずに初回の DELETE で 204 を返し、リトライ時に 404 を返すと、回避可能なリトライエラーが発生します。
  • { "error": ... } を含む 200 を返すと、監視システムや SDK がビジネスロジックの失敗を成功として分類してしまいます。
  • 新しい ETag を必要とする更新の後に 204 を返しながらレスポンスヘッダーを省略すると、安全なキャッシュや並行性制御が妨げられます。

テストと検証のチェックリスト

すべてのエンドポイントにおいて、ステータス、ボディ、Content-Type、ETag、およびキャッシュヘッダーに対するコントラクトテストを作成します。初回および繰り返しの DELETE、空のコレクション、存在しない単一リソース、表現あり/なしの更新、202 非同期分岐、プロキシ転送、および SDK デコードを網羅します。OpenAPI から少なくとも 1 つのクライアントを生成し、204 が JSON パースエラーを引き起こさないことを検証します。監視システムが 2xx、404、および構造化されたビジネスエラーを正しく分離していることを確認します。

フォローアップの質問

204 に ETag やその他のレスポンスヘッダーを含めることはできますか?

はい。メッセージコンテンツを禁止しても、メタデータを禁止することにはなりません。ETag、キャッシュ制御、または trace ID は並行性制御や診断をサポートできますが、それらが存在する条件を文書化してください。

空のページは 200 と 204 のどちらにすべきですか?

表現がリストである場合は、空の配列とページネーションメタデータを伴う 200 を推奨します。「表現を伴わない成功」が明示的であり、すべてのクライアントがボディの非存在を処理できる場合にのみ 204 を検討してください。

リソースが存在しない場合、DELETE は必ず 404 を返すべきですか?

常にそうとは限りません。削除が「リソースが存在しない状態を保証する」ことを意味する場合、繰り返しのリクエストに対して 204 を返すことができます。呼び出し元が存在していたかどうかを知る必要がある場合は 404 を返します。ドキュメント、SDK、および監視システム全体で、その選択を一貫して記録してください。

公開情報ソース

関連する質問