Backend Python i FastAPI — nowoczesne, skalowalne API
FastAPI to referencyjny framework Pythona do asynchronicznych API REST. Łączy natywne adnotacje typów Pythona z automatyczną walidacją Pydantic, samoczynnie generowaną dokumentacją OpenAPI i wydajnością ASGI porównywalną z Node.js — bez rezygnacji z czytelności kodu.
FastAPI — najszybszy framework Pythona
FastAPI działa na Uvicornie (serwer ASGI), a na produkcji z Gunicornem w trybie wieloprocesowym. Prosty endpoint czytający z cache'a Redisa nie wykonuje przy trafieniu w cache zapytania do bazy danych. Natywne wstrzykiwanie zależności pozwala testować każdą warstwę w izolacji, bez skomplikowanych mocków: uwierzytelnianie, sesja bazy danych i ograniczanie liczby żądań to osobne, wstrzykiwalne zależności.
Dokumentacja OpenAPI 3.1 powstaje automatycznie z adnotacji typów — w środowisku deweloperskim Swagger UI i ReDoc są dostępne pod `/docs` i `/redoc`. Schemat Pydantic v2 (walidator napisany w Ruście) sprawdza żądania i odpowiedzi 10–20 razy szybciej niż Pydantic v1. Każde nieprawidłowe pole zwraca kod 422 z czytelnymi, przetłumaczonymi komunikatami błędów.
- Natywne async/await — nieblokujące operacje wejścia-wyjścia przy wszystkich zapytaniach do bazy i HTTP
- BackgroundTasks do pracy wykonywanej po odesłaniu odpowiedzi (e-mail, webhook, log)
- Natywna obsługa WebSocket dla funkcji czasu rzeczywistego (czat, powiadomienia)
- Ograniczanie liczby żądań przez slowapi (na bazie limits) — na adres IP i na użytkownika
- Middleware CORS, kompresji (gzip/brotli), identyfikatora żądania i pomiaru czasu
PostgreSQL, SQLAlchemy i Alembic
Do wszystkich operacji na bazie używamy SQLAlchemy 2.0 async (sterownik asyncpg). Modele definiujemy typami Mapped — bezpiecznie typowane, bez ciągów znaków. Złożone zapytania piszemy w SQLAlchemy Core (sprawdzanym na etapie kompilacji) albo w czystym SQL przez `text()` z parametrami wiązanymi, nigdy przez sklejanie ciągów znaków, co całkowicie wyklucza wstrzyknięcie SQL.
Migracje Alembic są generowane automatycznie na podstawie zmian w modelach i przeglądane ręcznie przed zastosowaniem. Każda migracja ma przetestowane `upgrade()` i `downgrade()`. Na produkcji migracje uruchamiają się w CI przed wdrożeniem, więc baza danych zawsze pozostaje zsynchronizowana z kodem. Pulą połączeń zarządza asyncpg, a jej rozmiar konfiguruje się osobno dla każdej usługi.
- Blokowanie na poziomie wiersza przez `SELECT ... FOR UPDATE` przy krytycznych operacjach współbieżnych
- Wyszukiwanie pełnotekstowe z pg_trgm i tsvector — w prostych przypadkach bez Elasticsearcha
- JSONB dla danych półstrukturalnych, z indeksami GIN
- Tabele partycjonowane dla tabel liczących miliony wierszy (logi, zdarzenia)
Cache w Redisie i skalowanie poziome
Redis 7 pełni rolę cache'a aplikacji (TTL osobno dla każdego endpointu), magazynu sesji (tokeny odświeżające JWT z selektywnym unieważnianiem), mechanizmu pub/sub dla zdarzeń czasu rzeczywistego oraz kolejki zadań w tle (Celery albo ARQ). Strategia buforowania to cache-aside z jawną inwalidacją, a nie ślepy TTL, który mógłby podać nieaktualne dane.
- Uwierzytelnianie JWT z tokenem dostępu (15 minut) i tokenem odświeżającym w Redisie (7 dni)
- Celery z Redisem jako brokerem do zadań asynchronicznych (generowanie PDF, e-maile, importy)
- Endpoint health check `/health` ze stanem bazy danych, Redisa i wersją wdrożenia
- Ustrukturyzowane logowanie w JSON (structlog) — zgodne z Loki, Datadog i ELK
Zalety i ograniczenia
Zalety
- Wydajność ASGI porównywalna z Node.js i Go przy operacjach wejścia-wyjścia.
- Dokumentacja OpenAPI generowana automatycznie z adnotacji typów.
- Szybka walidacja Pydantic v2 z czytelnymi błędami 422.
- Czytelny kod — Python jest znany większości zespołów.
Ograniczenia
- Python pozostaje wolniejszy niż Go czy Rust przy zadaniach mocno obciążających procesor.
- async/await wymaga dyscypliny — jedno blokujące wywołanie zatrzymuje całą pętlę zdarzeń.
- Młodszy ekosystem niż Django, jeśli chodzi o gotowe funkcje w standardzie.
- Nie zawiera wbudowanego ORM-a ani panelu administracyjnego — wybiera się je osobno.
Krótki werdykt
Wybierz FastAPI do asynchronicznych API REST, mikrousług oraz backendów dla aplikacji SPA i mobilnych. Przy skrajnie dużym obciążeniu procesora lepiej sprawdzi się Go, a przy monolicie z gotowym panelem administracyjnym — Django.
Tabela specyfikacji
| Możliwość | Limit / próg | Typowe zastosowanie | |
|---|---|---|---|
| Współbieżność | async/await, nieblokujące wejście-wyjście | Zadania obciążające procesor wymagają osobnych workerów | API z wieloma zapytaniami do bazy i HTTP |
| Opóźnienie | Niskie opóźnienie na endpointach z cache'em Redisa | Rośnie przy serializacji dużych ładunków danych | Backendy SaaS, mobilne i czasu rzeczywistego |
| Walidacja i dokumentacja | Pydantic v2 i automatyczne OpenAPI 3.1 | Złożone schematy wydłużają uruchamianie | Publiczne API ze Swaggerem lub ReDoc |
| Typowy koszt | Open source, działa na 1 vCPU | Skalowanie poziome wymaga wielu procesów | Od MVP po produkcję |
FastAPI a rozwiązania alternatywne
| Kryterium | FastAPI | Django / Express |
|---|---|---|
| Wydajność asynchroniczna | Znakomita (natywne ASGI) | Django częściowo, Express dobra |
| Automatyczna dokumentacja OpenAPI | Tak, z adnotacji typów | Wymaga dodatkowych pakietów |
| Wbudowany panel i ORM | Nie (wybierane osobno) | Django: tak; Express: nie |
Najczęstsze pytania
Czy FastAPI jest szybszy od Django?
Przy operacjach wejścia-wyjścia tak. FastAPI działa asynchronicznie na ASGI, więc obsługuje znacznie więcej równoczesnych żądań z zapytaniami do bazy lub HTTP niż klasyczne, synchroniczne Django. Django ma za to więcej funkcji w standardzie.
Do czego FastAPI się nie nadaje?
Przy zadaniach mocno obciążających procesor (przetwarzanie obrazów, ciężkie obliczenia numeryczne) Python jest wolniejszy niż Go czy Rust — taką pracę przenosi się na osobne workery. FastAPI nie oferuje też gotowego panelu administracyjnego, jaki ma Django.
Czy FastAPI potrzebuje ORM-a?
Niekoniecznie. My używamy SQLAlchemy 2.0 async wraz z Alembikiem do migracji, ale można pisać też czysty SQL. ORM nie jest wbudowany, więc dobiera się go do projektu.
Jak skalować backend na FastAPI?
Poziomo: uruchamia się wiele procesów Uvicorna pod Gunicornem, za load balancerem, z cache'em w Redisie i ciężkimi zadaniami przeniesionymi do Celery. Bezstanowa architektura pozwala dokładać kolejne instancje w miarę potrzeb.