Python & FastAPI-backend — moderne, skalerbare API'er
FastAPI er det førende Python-framework til asynkrone REST-API'er. Det kombinerer Pythons native type hints med automatisk Pydantic-validering, automatisk genereret OpenAPI-dokumentation og ASGI-ydeevne på niveau med Node.js — uden at ofre kodens læsbarhed.
FastAPI — det hurtigste Python-framework
FastAPI kører på Uvicorn (ASGI-server) med Gunicorn til flere processer i produktion. Et simpelt endpoint, der læser fra Redis-cachen, svarer på under 5 ms på standardhardware. Indbygget Dependency Injection gør det muligt at teste hvert lag isoleret uden komplekse mocks: autentificering, databasesession og rate limiting er hver især en injicerbar afhængighed.
OpenAPI 3.1-dokumentation genereres automatisk ud fra type hints — Swagger UI og ReDoc er tilgængelige på `/docs` og `/redoc` under udvikling. Pydantic v2-skemaet (en validator baseret på Rust) validerer forespørgsler og svar 10–20 gange hurtigere end Pydantic v1. Ethvert ugyldigt felt returnerer en 422 med klare, lokaliserede fejlmeddelelser.
- Indbygget async/await — ikke-blokerende I/O på alle DB- og HTTP-operationer
- BackgroundTasks til operationer efter svaret (e-mail, webhook, log)
- Indbygget WebSocket-understøttelse til realtidsfunktioner (chat, notifikationer)
- Rate limiting med slowapi (limits-baseret) — pr. IP og pr. bruger
- CORS, komprimering (gzip/brotli), request ID, timing-middleware
PostgreSQL, SQLAlchemy og Alembic
Vi bruger SQLAlchemy 2.0 async (asyncpg-driver) til alle DB-operationer. Modeller defineres med Mapped-typer — typesikkert, uden strenge. Komplekse forespørgsler skrives i SQLAlchemy Core (tjekket ved kompilering) eller i ren SQL via `text()` med bind-parametre — aldrig strenginterpolation (fuldstændig forebyggelse af SQLi).
Alembic-migreringer autogenereres ud fra modelændringer og gennemgås manuelt, før de anvendes. Hver migrering har testede `upgrade()` og `downgrade()`. I produktion kører migreringerne i CI før udrulning — databasen er altid synkroniseret med koden. Connection pooling via asyncpg med konfigurerbar poolstørrelse pr. tjeneste.
- Rækkelåsning med `SELECT ... FOR UPDATE` til kritiske samtidige operationer
- Fuldtekstsøgning med pg_trgm og tsvector — ingen Elasticsearch i simple tilfælde
- JSONB til semistrukturerede data med GIN-indeksering
- Partitionerede tabeller til tabeller med millioner af rækker (logs, events)
Redis-caching og horisontal skalerbarhed
Redis 7 bruges til applikationscache (TTL pr. endpoint), sessionslager (JWT refresh-tokens med selektiv tilbagekaldelse), pub/sub til realtidshændelser og køer til baggrundsjob (Celery eller ARQ). Cachestrategien er cache-aside med eksplicit invalidering — ikke en blind TTL, der kan levere forældede data.
- JWT-autentificering med access-token (15 min) + Redis refresh-token (7 dage)
- Celery + Redis-broker til asynkrone opgaver (PDF-generering, e-mail, importer)
- Health check-endpoint `/health` med status for DB og Redis samt udrulningsversion
- Struktureret JSON-logning (structlog) — kompatibel med Loki/Datadog/ELK
Fordele og begrænsninger
Fordele
- ASGI-ydeevne på niveau med Node.js og Go på I/O.
- OpenAPI-dokumentation genereres automatisk ud fra type hints.
- Hurtig Pydantic v2-validering med klare 422-fejl.
- Læsbar kode, og Python er kendt af de fleste teams.
Begrænsninger
- Python er stadig langsommere end Go eller Rust på CPU-tunge opgaver.
- async/await kræver disciplin — ét blokerende kald standser hele event loopet.
- Yngre økosystem end Django, hvad angår batteries-included-funktioner.
- Ingen indbygget ORM eller admin — du vælger dem separat.
Kort konklusion
Vælg FastAPI til asynkrone REST-API'er, mikrotjenester og backends til SPA/mobil. Til ekstremt CPU-tunge apps eller monolitter med en færdig admin kan henholdsvis Go eller Django passe bedre.
Specifikationstabel
| Egenskab | Grænse / tærskel | Typisk anvendelse | |
|---|---|---|---|
| Samtidighed | async/await, ikke-blokerende I/O | CPU-tunge opgaver kræver separate workers | API'er med mange DB-/HTTP-kald |
| Latenstid | < 5 ms pr. endpoint med Redis-cache | Vokser med serialisering af store payloads | SaaS, mobil, realtids-backend |
| Validering og dokumentation | Pydantic v2 + automatisk OpenAPI 3.1 | Komplekse skemaer øger opstartstiden | Offentlige API'er med Swagger/ReDoc |
| Typisk pris | Open source, kører på 1 vCPU | Horisontal skalering kræver flere processer | Fra MVP til produktion |
FastAPI vs. alternativer
| Kriterium | FastAPI | Django / Express |
|---|---|---|
| Asynkron ydeevne | Fremragende (indbygget ASGI) | Django delvist, Express godt |
| Automatisk OpenAPI-dokumentation | Ja, ud fra type hints | Kræver ekstra pakker |
| Indbygget admin / ORM | Nej (vælges separat) | Django: ja; Express: nej |
Ofte stillede spørgsmål
Er FastAPI hurtigere end Django?
Ja på I/O. FastAPI kører asynkront på ASGI og håndterer derfor langt flere samtidige forespørgsler med DB-/HTTP-kald end klassisk synkron Django. Django har til gengæld flere indbyggede funktioner.
Hvad er FastAPI ikke egnet til?
Til meget CPU-tunge opgaver (billedbehandling, tunge numeriske beregninger) er Python langsommere end Go eller Rust; dem flytter man til separate workers. Der mangler også en færdig admin som i Django.
Kræver FastAPI en ORM?
Ikke obligatorisk. Vi bruger SQLAlchemy 2.0 async med Alembic til migreringer, men du kan skrive ren SQL. ORM'en følger ikke med, så du vælger den pr. projekt.
Hvordan skalerer jeg en FastAPI-backend?
Horisontalt: kør flere Uvicorn-processer under Gunicorn bag en load balancer, med Redis-cache og tunge opgaver flyttet til Celery. Stateless design gør det muligt at tilføje instanser efter behov.