Какой HTTP статус-код возвращать, если ресурс не найден в базе данных?

Ответ

При отсутствии конкретного запрашиваемого ресурса в базе данных наиболее подходящим HTTP статус-кодом является 404 Not Found. Этот код указывает, что сервер не может найти ресурс по указанному URL.

Почему 404 Not Found?

  • Семантика: Четко сообщает клиенту, что ресурс по указанному URL не существует.
  • Стандарт: Общепринятый стандарт для таких ситуаций, что упрощает обработку ошибок на стороне клиента.

Пример (FastAPI):

from fastapi import FastAPI, HTTPException
from typing import Optional

app = FastAPI()

# Предположим, у нас есть функция для получения элемента из БД
def get_item_from_db(item_id: int) -> Optional[dict]:
    # Имитация обращения к БД
    if item_id == 1:
        return {"id": 1, "name": "Test Item"}
    return None

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    item = get_item_from_db(item_id)
    if item is None:
        # Если ресурс не найден, выбрасываем HTTPException с 404 статусом
        raise HTTPException(status_code=404, detail=f"Item with id {item_id} not found")
    return item

Альтернативные сценарии и коды:

  • 200 OK с пустым списком/массивом: Если запрос предполагает возврат коллекции (например, /users), и коллекция пуста, следует вернуть 200 OK с пустым JSON-массивом ([]). Это означает, что запрос успешно обработан, но данных нет.
  • 204 No Content: Используется, когда запрос успешно обработан, но сервер не возвращает никакого содержимого (например, после успешного удаления ресурса).
  • 400 Bad Request: Если запрос некорректен (например, неверный формат ID), а не ресурс отсутствует.

Ответ 18+ 🔞

А, ну вот, классика жанра! Ты пишешь API, а там какой-то ресурс не находится, и думаешь: "Какой же статус-код вернуть, чтобы всем было понятно, что мы тут нихуя не нашли?"

Так вот, слушай сюда, запоминай раз и навсегда, как отче наш: 404 Not Found. Это твой верный пёс, твоя Муму в мире HTTP, если угодно. Он кричит клиенту на чистейшем языке протокола: "Э, дружок-пирожок, по этому адресу у нас ни хуя нет! Иди искать в другом месте".

А почему именно 404, а не какая-нибудь хуйня с горы?

  • Понятно всем, даже мартышке: Семантика прозрачнее некуда. "Не найдено" — значит, не найдено. Никаких двойных толкований, в рот меня чих-пых.
  • Стандарт, блядь!: Все так делают. Все фронтендеры, все библиотеки для запросов заточены под то, что 404 — это провал поиска. Не надо изобретать велосипед с квадратными колёсами.

Смотри, как это выглядит в коде (на примере FastAPI):

from fastapi import FastAPI, HTTPException
from typing import Optional

app = FastAPI()

# Допустим, у нас есть функция, которая лезет в базу
def get_item_from_db(item_id: int) -> Optional[dict]:
    # Имитируем запрос. Если id=1, то нашли, если нет — хуй там.
    if item_id == 1:
        return {"id": 1, "name": "Test Item"}
    return None  # Вот тут-то и пустота, блядь!

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    item = get_item_from_db(item_id)
    if item is None:
        # Ага! Не нашли! Вот тут и даём ему 404 прямо в ебало!
        raise HTTPException(status_code=404, detail=f"Item with id {item_id} not found")
    return item

А теперь, чтобы ты не облажался, про альтернативы:

  • 200 OK, но с пустым массивом []: Это когда запрос сам по себе хороший, но данных просто нет. Например, запросил список пользователей (/users), а они все сбежали. Запрос-то обработан успешно, вот и 200, но список пустой. Не путай с ситуацией, когда ищут ОДНУ конкретную сущность по ID — там уже 404.
  • 204 No Content: Это когда всё прошло охуенно, но тебе нечего сказать в ответ. Типа "удалил ресурс — и молчи в тряпочку". Никакого тела ответа, только заголовки.
  • 400 Bad Request: А это уже совсем другая история, ёпта! Это когда клиент прислал какую-то дичь в запросе — кривой ID, не тот формат данных. Проблема не в том, что мы не нашли, а в том, что искать-то было нечего, потому что запрос — манда с ушами. Не путай!

Короче, правило простое: искали одну штуку по уникальному ключу (ID, slug) — не нашли? 404, детка. И не мудри.