Полное и частичное обновление
Содержание курса
В прошлом уроке мы добавили get_room_or_404 — вспомогательную функцию, которая либо возвращает найденную переговорную, либо сразу отдаёт 404. Теперь эта функция будет работать в обоих обработчиках обновления: PUT для полной замены и PATCH для изменения только присланных полей.
PUT /api/rooms/{room_id}: замена name и capacity
PUT в этом API означает полную замену записи: клиент обязан прислать все поля, а сервер перезаписывает их целиком, не сохраняя ничего из старых значений.
Для тела запроса используем уже знакомую RoomIn — она требует name и capacity с теми же ограничениями, что и при создании. Маршрут возвращает обновлённую переговорную через response_model=RoomOut.
@app.put("/api/rooms/{room_id}", response_model=RoomOut)
def update_room(room_id: int, room: RoomIn):
existing = get_room_or_404(room_id)
rooms_db[room_id] = {"id": room_id, "name": room.name, "capacity": room.capacity}
return rooms_db[room_id]
Порядок действий здесь принципиален. Сначала get_room_or_404 проверяет существование записи — если её нет, функция сразу выбрасывает HTTPException(404) и дальше ничего не происходит. Только после успешной проверки обработчик записывает новый словарь в rooms_db. id берётся из пути, а не из тела запроса — так он не может быть перезаписан клиентом случайно.
Запись с id=1 уже существует, а с id=99 — нет. Результат PUT зависит от тела и выбранного id:
Полное тело — запись меняется, ответ 200:
PUT /api/rooms/1
{"name": "Переговорная Альфа", "capacity": 12}
Сервер вернёт {"id": 1, "name": "Переговорная Альфа", "capacity": 12}. Последующий GET /api/rooms/1 покажет те же данные.
Пропущено обязательное поле — 422, запись не тронута:
PUT /api/rooms/1
{"name": "Переговорная Альфа"}
RoomIn требует capacity, и FastAPI вернёт 422 ещё до вызова функции. rooms_db не изменится.
Несуществующий id — 404:
PUT /api/rooms/99
{"name": "Переговорная Альфа", "capacity": 12}
get_room_or_404(99) выбрасывает 404. Это поведение нашего конкретного API: мы решили не создавать новую запись по произвольному id через PUT. Другие API могут делать иначе — это не стандарт HTTP, а контракт конкретного сервиса.
