コンテンツにスキップ

DELETE API設計:既に削除済みユーザーに204を返すか404を返すか

問題

DELETE /users/1 Should it return 204 or 404, if the user is already deleted?

解答

どちらも正解であり得る。ただし実務では 204 を推奨するケースが多い。

解説

204 No Content を返す場合(冪等性重視)

DELETE /users/1
→ 1回目: ユーザー削除 → 204 No Content
→ 2回目: 既に削除済み → 204 No Content(同じ結果)

理由: - HTTP の DELETE メソッドは冪等(idempotent)であるべき - 「ユーザー1が存在しない」という最終状態は、1回目も2回目も同じ - クライアントは「削除できた」として安全に処理を続けられる - 分散システムやリトライ処理でのエラーハンドリングがシンプルになる

404 Not Found を返す場合(厳密な意味論重視)

DELETE /users/1
→ 1回目: ユーザー削除 → 200 or 204
→ 2回目: 既に削除済み → 404 Not Found

理由: - 「存在しないリソースへの操作」を明示したい - クライアントが「本当に削除したか」vs「そもそも存在しなかったか」を区別できる - REST の純粋な意味論(リソースが見つからない = 404)に準拠

RFC 9110 の立場

HTTP 仕様(RFC 9110)は DELETE の冪等性を定義しているが、ステータスコードの選択は実装次第と述べている。ただし「意図した最終状態が達成されている場合は 2xx が適切」というニュアンスがある。

実務での判断基準

┌─────────────────────────────────────────────────────────┐
│ リトライ・冪等性が重要(分散システム、モバイルアプリ)    │
│ → 204 を推奨                                            │
│                                                         │
│ クライアントが「削除したか / 元々なかったか」を区別する必要 │
│ → 404 を返してもよい                                     │
│                                                         │
│ 監査ログや論理削除がある場合                              │
│ → 論理削除 → 204(物理的には存在する)                    │
└─────────────────────────────────────────────────────────┘

コード例(Go)

func deleteUser(w http.ResponseWriter, r *http.Request) {
    id := chi.URLParam(r, "id")

    err := db.DeleteUser(id)

    // 冪等性重視: 既に削除済みでも 204
    if err == ErrNotFound {
        w.WriteHeader(http.StatusNoContent) // 204
        return
    }
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }

    w.WriteHeader(http.StatusNoContent) // 204
}

Stripe・GitHub などの有名 API の事例

サービス DELETE 後の挙動
Stripe 削除済みオブジェクトは { "deleted": true } を 200 で返す
GitHub 存在しないリソースには 404
Twilio 冪等性を明示し、2回目の DELETE にも 204

面接でのポイント

  • 「どちらが正しいか」より「なぜそう設計するか」を答える: 冪等性・クライアントの要件・チームのコンベンションを根拠にする
  • 冪等性(Idempotency)の概念を説明できること: 同じリクエストを複数回送っても結果が変わらない性質
  • HTTP メソッドの意味論を理解していること: GET(冪等 + 安全)、PUT(冪等)、DELETE(冪等)、POST(非冪等)
  • 実際のプロジェクトでの決定経験があれば話す: チームで議論して決めたことを示すと好印象