Если представить ваше согласие на вызов функции REST API как игру, маршрутизация — это как меню в кафе. Вы открываете его, смотрите, что можно заказать (запросить), и официант приносит вам то, что вы хотите. Но в мире программирования официантом выступает сервер, а "блюда" — это функции и данные вашего приложения. Эндпоинты — это определённые маршруты (адреса) на вашем сервере, которые связывают конкретный запрос пользователя с конкретной обработкой в коде.
Например:
- URL:
/get-users→ Сервер: "Ага, надо запустить функцию для получения списка пользователей". - URL:
/add-user→ Сервер: "Понял, добавить нового пользователя".
FastAPI делает это настолько просто и элегантно, что программистам даже нравится работать с ним. Честно.
Как создаются маршруты в FastAPI?
FastAPI использует декораторы для определения маршрутов. Декоратор — это такой "магический" инструмент, который позволяет модифицировать функции. В случае FastAPI он превращает обычную Python-функцию в обработчик запросов.
Вот базовый пример:
from fastapi import FastAPI
app = FastAPI()
@app.get("/hello")
async def say_hello():
return {"message": "Привет, FastAPI!"}
Что тут происходит:
@app.get("/hello")— мы говорим FastAPI: "Слушай, если кто-то приходит на маршрут/helloметодом GET, вызывкай функциюsay_hello".- Функция
say_helloвозвращает JSON-ответ с приветствием. - Voilà! У вас минимальный рабочий эндпоинт.
Теперь это можно запустить с помощью Uvicorn, открыть в браузере http://127.0.0.1:8000/hello и увидеть JSON-ответ: {"message": "Привет, FastAPI!"}.
Типы HTTP-методов и их декораторы
FastAPI поддерживает все основные HTTP-методы, такие как GET, POST, PUT, DELETE и другие. Вы можете использовать их следующим образом:
| HTTP Метод | Декоратор FastAPI | Пример маршрута |
|---|---|---|
| GET | @app.get() |
@app.get("/items") |
| POST | @app.post() |
@app.post("/items") |
| PUT | @app.put() |
@app.put("/items/{item_id}") |
| DELETE | @app.delete() |
@app.delete("/items/{item_id}") |
Пример использования POST-запроса:
@app.post("/create-item")
async def create_item(name: str):
return {"success": True, "item": name}
Если вы отправите POST-запрос с параметром name (например, через Postman или Curl), вы получите JSON-ответ с подтверждением.
Асинхронность в маршрутах
FastAPI поддерживает асинхронность "из коробки" благодаря магии async def. Асинхронные функции позволяют более эффективно работать с операциями ввода-вывода (например, запросами к базе данных). Если вы не используете async, приложение всё равно будет работать, но вы теряете преимущества асинхронности.
Пример:
@app.get("/async-example")
async def async_example():
return {"message": "Асинхронные маршруты работают как швейцарские часы"}
Маршруты с параметрами
Иногда вам нужно передать динамические данные через URL. Например, получить конкретного пользователя по его ID. Для этого используются параметры пути (Path Parameters).
Пример:
@app.get("/user/{user_id}")
async def get_user(user_id: int):
return {"user_id": user_id, "message": "Вот ваш пользователь!"}
Если вы отправите запрос на http://127.0.0.1:8000/user/42, FastAPI передаст значение 42 в параметр user_id функции get_user.
Параметры пути с проверкой типов
FastAPI автоматически проверяет типы данных параметров. Если вы укажете, что user_id должен быть int, а пользователь отправит строку, FastAPI вернёт ошибку.
Пример:
@app.get("/square/{number}")
async def square(number: int):
return {"number": number, "square": number ** 2}
Попробуйте отправить http://127.0.0.1:8000/square/abc и посмотрите, как FastAPI вернёт понятный ответ об ошибке.
Работа с несколькими маршрутами
FastAPI поддерживает организацию нескольких маршрутов в одном приложении. Например:
@app.get("/")
async def root():
return {"message": "Добро пожаловать в наше API!"}
@app.get("/about")
async def about():
return {"info": "Это тестовое приложение."}
Теперь маршруты / и /about обрабатываются разными функциями.
Группировка маршрутов с помощью маршрутизаторов
Когда приложение начинает разрастаться, будет удобно группировать маршруты по логике их работы. Для этого FastAPI предлагает объект APIRouter.
Пример:
from fastapi import APIRouter
user_router = APIRouter()
@user_router.get("/users")
async def list_users():
return {"users": ["Alice", "Bob", "Charlie"]}
@user_router.post("/users")
async def create_user(name: str):
return {"user": name, "status": "created"}
# Подключаем маршрутизатор к основному приложению
app.include_router(user_router)
Теперь ваши маршруты /users и /users (POST) находятся под управлением user_router. Это значительно улучшает читаемость и масштабируемость проекта.
Особенности и подводные камни
При работе с маршрутизацией важно помнить несколько моментов:
- Конфликты маршрутов: Если вы создадите два одинаковых маршрута (например,
/items) с разными методами, FastAPI выдаст ошибку. Убедитесь, что ваши маршруты уникальны или корректно настроены. - Порядок обработки: FastAPI обрабатывает маршруты в порядке их определения в коде. Если у вас есть два похожих маршрута, как
/itemsи/items/{item_id}, размещайте более специфичный маршрут выше. - Типизация параметров: Не злоупотребляйте отсутствием типов. Проверка типов — ваш друг в здравом программировании.
Практическое задание
- Реализуйте два маршрута:
/math/sum/{a}/{b}— принимает два числа (aиb) и возвращает их сумму./math/multi/{a}/{b}— умножает два числа.
- Разделите маршруты на два группы с использованием
APIRouter:- Группа "math".
- Группа "operations".
- Запустите приложение и протестируйте все маршруты.
FastAPI делает создание маршрутов таким простым и увлекательным, что разработчики иногда забывают, что создают сложную логику. В следующей лекции мы углубимся в работу с параметрами запросов (Query Parameters) и попробуем расширить наше мини-приложение новыми крутыми функциями.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ