Структура проєкту¶
FastAPI не диктує розкладку проєкту. Немає startproject, немає
settings.py, немає поняття «застосунків», які ви реєструєте. Проєкт може
бути одним файлом main.py і розростатися в пакет, коли цей файл стає
завеликим. Цей розділ показує, як він росте — і як це зіставляється з
поділом на проєкт/застосунок у Django.
Єдиний інструмент: APIRouter¶
Щойно одного файлу стає замало, ви розбиваєте маршрути на роутери.
APIRouter — це міні-колекція операцій шляху, яку ви будуєте в окремому
модулі, а потім приєднуєте до застосунку:
# app/routers/items.py
from fastapi import APIRouter, HTTPException
router = APIRouter(prefix="/items", tags=["items"])
ITEMS = [{"id": 1, "name": "Widget"}, {"id": 2, "name": "Gadget"}]
@router.get("")
def list_items():
return {"items": ITEMS}
@router.get("/{item_id}")
def get_item(item_id: int):
for item in ITEMS:
if item["id"] == item_id:
return item
raise HTTPException(status_code=404, detail="Item not found")
APIRouter поводиться як FastAPI для оголошення маршрутів — ті самі
декоратори @router.get(...) — але сам по собі нічого не обслуговує. Ви
під'єднуєте його до застосунку через include_router:
# app/main.py
from fastapi import FastAPI
from app.routers import items, users
app = FastAPI(title="Project Structure (FastAPI)")
app.include_router(items.router)
app.include_router(users.router)
@app.get("/")
def read_root():
return {"message": "It works!"}
prefix="/items" на роутері означає, що його маршрути живуть під /items
("" → /items, /{item_id} → /items/{item_id}). tags=["items"]
групує їх в UI /docs. Це і весь механізм: будуєте роутери в модулях,
include_router їх у main.py.
З досвіду Django:
include_router(items.router)— прямий відповідникpath("", include("items.urls")).APIRouterізprefix— це, по суті,urls.pyзастосунку з приєднаним URL-префіксом. Але це все, чим він є — група маршрутів. Django-застосунок — це набагато більше: набірmodels.py, міграцій,admin.py, шаблонів іurls.py, зареєстрований вINSTALLED_APPS. Роутер не несе нічого з цього. Тож один Django-застосунок зазвичай стає на боці FastAPI просто модулем-роутером (плюс окремі модулі для моделей/схем/залежностей, які ви додасте згодом).
Розкладка, що масштабується¶
Стандартна для спільноти форма застосунку, що росте, — це пакет із
підпакетом routers/ (або routers/api):
app/
├── __init__.py
├── main.py # creates FastAPI(), includes the routers
└── routers/
├── __init__.py
├── items.py # APIRouter(prefix="/items")
└── users.py # APIRouter(prefix="/users")
Запускайте це через fastapi dev app/main.py (або
uvicorn app.main:app --reload). У міру зростання проєкту ви додаєте
сусідні модулі — models.py, schemas.py, dependencies.py,
database.py, config.py — туди, де, на вашу думку, їм місце. Жодна з цих
назв не нав'язана; це домовленості, а не правила фреймворку.
З досвіду Django: Дві звички, від яких треба відучитися.
По-перше, немає
INSTALLED_APPSі немає реєстру застосунків. Нічого не автовиявляється.main.pyімпортує кожен роутер і явно викликаєinclude_router— що ви імпортували, те й працює. Немаєapps.py, немаєAppConfig, немає хукаready(), немає фази завантаження застосунків.По-друге, поділу на проєкт/застосунок не існує. Django дає вам проєкт (
config/), що володіє налаштуваннями та кореневим URLconf, і застосунки, які до нього під'єднуються. У FastAPI є лише «ваш код»: екземплярFastAPI()і ті модулі, які ви в нього імпортуєте.main.pyграє суміщену роль підключенняsettings.pyі кореневогоurls.py, але ви збираєте це вручну.
Роутери роблять трохи більше, ніж групують URL¶
APIRouter також може приєднати prefix, tags, dependencies та
типові responses до кожного маршруту, який він тримає, а роутери можуть
включати інші роутери — тож ви можете будувати дерево (/api/v1/items),
вкладаючи їх:
api = APIRouter(prefix="/api/v1")
api.include_router(items.router) # -> /api/v1/items
api.include_router(users.router) # -> /api/v1/users
app.include_router(api)
З досвіду Django: Вкладання роутерів для побудови
/api/v1/...— це те, що роблять вкладені викликиinclude()в URLconf Django.dependencies=[...]на рівні роутера (кожен маршрут у роутері їх виконує) — приблизний відповідник обгортання в'ю застосунку в middleware чи спільний декоратор, але з областю дії роутера — і це належно розглянуто в темі про впровадження залежностей.
Супровідні проєкти¶
Розкладка вище, побудована обома способами, у каталозі 04-demo/ цього
розділу:
04-demo/fastapi/(завантажити) — пакетapp/ізrouters/items.pyтаrouters/users.py, з'єднані вapp/main.py.04-demo/django/(завантажити) — проєктconfig/із застосункамиitems/таusers/, коженinclude()-нутий уconfig/urls.py.
Обидва надають той самий API /items та /users; їхні тести перевіряють
однакові відповіді. FastAPI: pytest (7 тестів). Django: manage.py test
(6 тестів, розподілених між двома застосунками).