Ответ
При отсутствии конкретного запрашиваемого ресурса в базе данных наиболее подходящим 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, детка. И не мудри.