Мы уже сделали наши первые шаги в FastAPI и даже запустили простенькое приложение. Время углубиться в один из ключевых аспектов любого веб-приложения — маршруты и обработку запросов. В этой статье разберёмся, как создавать маршруты, работать с параметрами и валидировать данные.

Маршруты (routes) определяют, как сервер обрабатывает запросы от клиентов (например, вашего браузера или мобильного приложения). Каждый маршрут привязан к определённому URL и HTTP-методу (GET, POST, PUT, DELETE и т.д.). FastAPI позволяет легко создавать маршруты и настраивать их поведение с помощью декораторов.

Базовые маршруты

Начнём с простого примера. Допустим, у нас есть магазин, и мы хотим создать маршрут для отображения списка товаров.

from fastapi import FastAPI

app = FastAPI()

@app.get("/products")
def get_products():
    return {"products": ["Телефон", "Ноутбук", "Наушники"]}

Здесь:

  • @app.get(«/products») — декоратор, который привязывает функцию к URL /products и HTTP-методу GET.
  • Функция get_products() возвращает список товаров в виде словаря, который FastAPI автоматически преобразует в JSON.

Открываем http://127.0.0.1:8000/products и видим:

{"products": ["Телефон", "Ноутбук", "Наушники"]}

Просто? Ещё бы! Но давайте усложним задачу.

Параметры маршрута (Path Parameters)

Часто нам нужно передавать данные прямо в URL. Например, получить информацию о конкретном товаре по его ID.

@app.get("/products/{product_id}")
def get_product(product_id: int):
    return {"product_id": product_id, "name": "Пример товара"}

Теперь, если зайдём на http://127.0.0.1:8000/products/42, получим:

{"product_id": 42, "name": "Пример товара"}

Важно: FastAPI автоматически валидирует типы данных. Если передать строку вместо числа, будет ошибка 422 Unprocessable Entity. Например, http://127.0.0.1:8000/products/abc вызовет ошибку.

Необязательные параметры запроса (Query Parameters)

Что если мы хотим добавить фильтрацию? Например, вернуть товары только определённой категории. Для этого используются query-параметры.

@app.get("/products/")
def get_products(category: str = None):
    if category:
        return {"category": category, "products": ["Фильтрованные товары"]}
    return {"products": ["Телефон", "Ноутбук", "Наушники"]}

Теперь можно зайти на http://127.0.0.1:8000/products/?category=electronics и получить:

{"category": "electronics", "products": ["Фильтрованные товары"]}

Если параметр не передан, вернётся полный список товаров.

Совмещение path и query параметров

Конечно, никто не мешает комбинировать оба вида параметров. Например:

@app.get("/products/{product_id}")
def get_product_details(product_id: int, detailed: bool = False):
    if detailed:
        return {"product_id": product_id, "details": "Подробная информация о товаре"}
    return {"product_id": product_id, "details": "Краткая информация"}

Теперь запрос http://127.0.0.1:8000/products/10?detailed=true вернёт:

{"product_id": 10, "details": "Подробная информация о товаре"}

Валидация данных с Pydantic

FastAPI тесно интегрирован с Pydantic — мощной библиотекой для валидации данных. Давайте создадим маршрут для добавления нового товара с валидацией входных данных:

from pydantic import BaseModel

class Product(BaseModel):
    name: str
    price: float
    in_stock: bool

@app.post("/products/")
def create_product(product: Product):
    return {"message": "Товар создан", "product": product}

Теперь отправим POST-запрос на http://127.0.0.1:8000/products/ с телом:

{
    "name": "Мышка",
    "price": 25.5,
    "in_stock": true
}

FastAPI автоматически валидирует, что:

  • name — строка.
  • price — число.
  • in_stock — логическое значение.

Если что-то пойдёт не так, сервер вернёт ошибку с подробным описанием.

Заключение

Сегодня мы разобрались с маршрутами и параметрами в FastAPI, научились передавать данные через URL и запросы, а также посмотрели на базовую валидацию. В следующей статье перейдём к обработке ошибок и настройке ответов — это не менее увлекательно!

 

2 комментария