Якщо уявити вашу згоду на виклик функції 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-відповідь з привітанням. - Ось! У вас мінімальний робочий ендпоінт.
Тепер це можна запустити з допомогою 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) і спробуємо розширити наш мінідодаток новими крутяцькими фічами.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ