CRUD как HTTP-контракт

Создание ресурса: POST и статус 201

Содержание курса

rooms_db и next_id: сохранение переговорной обработчиком POST

Для учебного примера хранилище — обычный Python-словарь на уровне модуля. Рядом с ним объявляют счётчик:

rooms_db: dict[int, dict] = {}
next_id = 1

Оба имени живут в глобальной области модуля. Это значит, что все обработчики в том же файле работают с одним и тем же объектом — не с копиями.

Вот полный файл main.py с POST и GET:

from fastapi import FastAPI
from pydantic import BaseModel, Field

app = FastAPI()

rooms_db: dict[int, dict] = {}
next_id = 1

class RoomIn(BaseModel):
    name: str = Field(..., min_length=2, max_length=50)
    capacity: int = Field(..., ge=1, le=50)

class RoomOut(BaseModel):
    id: int
    name: str
    capacity: int

@app.post("/api/rooms", response_model=RoomOut, status_code=201)
def create_room(room: RoomIn):
    global next_id
    room_id = next_id
    rooms_db[room_id] = {"id": room_id, "name": room.name, "capacity": room.capacity}
    next_id += 1
    return rooms_db[room_id]

@app.get("/api/rooms/{room_id}", response_model=RoomOut)
def get_room(room_id: int):
    return rooms_db[room_id]

Что происходит внутри create_room при каждом вызове: функция сначала читает текущее значение next_id и сохраняет его в локальную переменную room_id. Затем записывает словарь с тремя полями в rooms_db под этим ключом. После этого увеличивает счётчик, чтобы следующий вызов получил уже другой id. Наконец, возвращает только что сохранённую запись — FastAPI пропустит её через RoomOut и отправит клиенту.

global next_id нужен именно здесь: без этого объявления Python считает присвоение next_id += 1 созданием новой локальной переменной и поднимает UnboundLocalError.

Если отправить два POST подряд в одном запущенном процессе, первый создаст запись с id=1, второй — с id=2. Обе записи останутся в rooms_db до завершения процесса. При перезапуске сервера словарь снова пустой, а счётчик снова равен 1 — никакой персистентности нет. Эта схема работает для последовательных запросов к одному процессу; при параллельных вызовах или нескольких воркерах согласованность id не гарантируется.