Первый работающий API

Query-параметры и фильтрация каталога

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

Path-параметры брали значения прямо из сегментов пути — /api/rooms/2 давал room_id = 2. Query-параметры устроены иначе: они находятся в части URL после ?. Именно с ними мы будем фильтровать каталог переговорных.

Как аргумент попадает из query-строки в функцию

Для простых аргументов int, str и bool FastAPI по умолчанию применяет такое правило: если имя аргумента функции совпадает с именем сегмента пути в фигурных скобках — значение берётся из пути. Если не совпадает — FastAPI ищет его в query-строке.

Вот конкретный пример. Маршрут объявлен как @app.get("/api/rooms") — без переменных сегментов. Тогда аргумент min_capacity: int = 0 получит значение из ?min_capacity=10, а не из пути, которого там попросту нет.

Имя в функции должно совпадать с именем параметра в URL. Если написать ?min_capacity=10, а в функции принять capacity, FastAPI не свяжет их: capacity будет искаться как отдельный query-параметр.

Здесь кроется частая ошибка при работе с path-параметрами. Возьмём маршрут:

@app.get("/api/rooms/{room_id}")
def get_room(id: int):
    ...

Аргумент называется id, а в шаблоне пути стоит {room_id}. FastAPI не свяжет id с сегментом пути — он будет ожидать ?id=... в query-строке. Запрос GET /api/rooms/1 без этого параметра получит ответ 422.

Исправление простое — согласовать имена:

@app.get("/api/rooms/{room_id}")
def get_room(room_id: int):
    ...

Теперь room_id найдётся в пути, и запрос GET /api/rooms/1 отработает корректно. Для фильтра списка ситуация обратная: min_capacity не упоминается в фигурных скобках маршрута "/api/rooms", поэтому FastAPI читает его из query-строки — никакой дополнительной аннотации для этого не нужно.