Python im Web

Django oder FastAPI: welches Framework zu eurem Dienst passt

Das eine bringt fast alles mit und gibt dafür Struktur vor, das andere bringt fast nichts mit und lässt euch die Wahl. Woran ihr festmacht, welche der beiden Rechnungen für euch aufgeht.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Seit 1997 am Markt Kleine Gruppen Präsenz und Live-Online Zertifizierte Trainer
Worum es geht

Entschieden wird nach einer Zahl, bezahlt wird an ganz anderer Stelle

Die Diskussion beginnt fast immer mit Durchsatz. Irgendwo steht ein Benchmark, in dem eine schlanke asynchrone Anwendung ein Vielfaches der Anfragen pro Sekunde schafft, und damit gilt die Sache als geklärt. In einem echten Dienst geht die Zeit aber in Datenbankabfragen, Serialisierung und Warten auf andere Systeme. Ein Wechsel des Frameworks verschiebt an dieser Verteilung wenig, er verschiebt vor allem, wie viel ihr selbst schreiben müsst.

In die eine Richtung falsch entschieden merkt ihr nach einem Vierteljahr. Der Dienst mit der schlanken Schnittstelle steht schnell, dann kommt die Anmeldung mit Rollen dazu, dann eine Oberfläche, in der die Fachabteilung Stammdaten pflegen kann, dann Migrationen für Schemaänderungen und schließlich ein Weg, Aufgaben im Hintergrund abzuarbeiten. Jedes einzelne Stück ist machbar, aber am Ende habt ihr ein eigenes Rahmenwerk gebaut und müsst es auch pflegen.

In die andere Richtung falsch entschieden merkt ihr langsamer. Für einen Dienst, der nichts weiter tut, als Nachrichten anzunehmen, zu prüfen und weiterzureichen, schleppt ihr eine Struktur mit, die für Anwendungen mit Datenbank und Oberfläche gemacht ist. Das ist kein Drama, kostet aber bei jedem neuen Kollegen Erklärzeit und bei jedem Container ein paar Sekunden Startzeit, die in einer Umgebung mit automatischer Skalierung durchaus zählen können.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Der direkte Vergleich

Die Kriterien, an denen die Entscheidung tatsächlich hängt

Verglichen wird nicht der Durchsatz in einem fremden Lastversuch, sondern das, was ihr über die Laufzeit des Dienstes merkt: mitgelieferter Umfang, Eignung für reine Schnittstellen, Verhalten unter vielen Verbindungen, Planbarkeit, Eigenanteil und Einarbeitung.

Django

vollständiges Rahmenwerk mit eigenem Datenzugriff, Wanderungsskripten, Anmeldung, Formularen und Verwaltungsoberfläche, mit festem Veröffentlichungsrhythmus und Langzeitfassungen

FastAPI

schlanke Schicht für JSON-Schnittstellen auf Basis von Starlette und Pydantic, mit automatisch erzeugter Schnittstellenbeschreibung und ohne eigenen Datenzugriff

Wie schnell steht ein Dienst mit Datenbank, Anmeldung und Datenpflege?

Django

Datenmodell, Schemaänderungen, Benutzer mit Rechten und eine brauchbare Verwaltungsoberfläche sind an einem Tag eingerichtet, weil alles davon mitgeliefert wird und aufeinander abgestimmt ist. Genau dafür wurde das Rahmenwerk gebaut.

FastAPI

Nichts davon ist enthalten. Datenzugriff und Wanderungsskripte kommen aus getrennten Bibliotheken, die Anmeldung baut ihr selbst oder bindet einen Anbieter an, und eine Pflegeoberfläche gibt es nicht. Jede dieser Entscheidungen ist für sich vertretbar, zusammen sind sie ein Projekt.

Wie gut passt es für eine reine JSON-Schnittstelle mit festem Vertrag?

Django

Möglich und verbreitet, aber über eine zusätzliche Schicht. Die Beschreibung der Schnittstelle entsteht dabei nicht von selbst aus den Typangaben, sondern über eigene Serialisierer oder ein Zusatzpaket, und das ist spürbar mehr Aufbau.

FastAPI

Das ist der Kern. Die Typangaben der Funktion sind gleichzeitig die Prüfung der Eingaben, die Umwandlung der Ausgaben und die maschinenlesbare Beschreibung der Schnittstelle. Wer Verträge zwischen Diensten pflegt, spart hier tatsächlich Arbeit.

Wie verhält es sich bei vielen gleichzeitig offenen Verbindungen?

Django

Django kann asynchron betrieben werden und bringt asynchrone Varianten für einen wachsenden Teil der Schnittstellen mit. Der Datenzugriff ist aber in weiten Teilen synchron gewachsen, weshalb im gemischten Betrieb Aufrufe in einen Thread-Pool ausgelagert werden und die Wirkung begrenzt bleibt.

FastAPI

Asynchron von Grund auf, mit einer sauberen Trennung zwischen asynchronen Funktionen und solchen, die in einem Thread-Pool laufen. Für Dienste, die überwiegend auf andere Systeme warten und viele Verbindungen offen halten, ist das die passendere Bauform.

Wie planbar ist der Unterbau über mehrere Jahre?

Django

Es gibt einen festen Veröffentlichungsrhythmus und ausgewiesene Langzeitfassungen. Die aktuelle LTS-Version 5.2 wird bis April 2028 mit Sicherheitsaktualisierungen versorgt, die nächste ist bereits als 6.2 angekündigt. Für Systeme mit langer Laufzeit und wenig Zuwendung ist das ein handfester Vorteil.

FastAPI

Das Projekt steht weiterhin bei einer Fassung aus der Reihe 0.x und veröffentlicht häufig. Dazu kommen zwei zentrale Abhängigkeiten, deren Entwicklung ihr ebenfalls verfolgen müsst. In der Praxis funktioniert das gut, es verlangt aber regelmäßige Pflege statt eines Sprungs alle zwei Jahre.

Wie viel müsst ihr selbst zusammensetzen und pflegen?

Django

Wenig. Sitzungen, Schutz vor gefälschten Anfragen, Formulare, Übersetzungen, Rechte und seit Version 6.0 auch Hintergrundaufgaben und eine eingebaute Unterstützung für Sicherheitsrichtlinien im Browser sind Teil des Rahmenwerks und werden gemeinsam gepflegt.

FastAPI

Viel. Jede der genannten Aufgaben ist eine eigene Auswahl, eine eigene Abhängigkeit und eine eigene Quelle für Sicherheitsmeldungen. Der Vorteil ist, dass ihr genau das nehmt, was ihr braucht, der Nachteil, dass diese Zusammenstellung euer Werk bleibt.

Wie schnell ist jemand produktiv, der neu dazukommt?

Django

Es gibt viel zu lernen, aber es ist überall dasselbe: Projekte sehen einander ähnlich, die Dokumentation ist umfangreich und seit Jahren gepflegt, und für fast jedes Problem existiert eine ausgetretene Lösung. Die ersten zwei Wochen sind anstrengender, danach trägt es.

FastAPI

Die Fläche des Rahmenwerks selbst ist klein und in einem Tag verstanden, vor allem für Leute, die schon mit Typannotationen arbeiten. Der Einstieg in ein konkretes Projekt hängt dafür stärker davon ab, welche Bibliotheken dort zusammengesetzt wurden, und das ist von Projekt zu Projekt verschieden.

Was passt wann

Wenn hinter dem Dienst ein fachliches Datenmodell steht, Menschen sich anmelden und jemand Stammdaten pflegen muss
nehmt Django und spart euch den Nachbau von Anmeldung, Rechten und Verwaltungsoberfläche.
Wenn der Dienst eine JSON-Schnittstelle mit festem Vertrag ist und die Daten woanders liegen
nehmt FastAPI und legt die Beschreibung der Schnittstelle aus den Typangaben heraus fest.
Wenn eine einzelne Schnittstelle in einer bestehenden Django-Anwendung besonders belastet oder besonders schnelllebig ist
lasst die Anwendung, wo sie ist, und zieht allein diese Schnittstelle als eigenen Dienst heraus.

Fünf Fragen, und die Wahl steht fest

  1. 01 Melden sich Menschen an und pflegen Daten? Dann zählt der mitgelieferte Umfang.
  2. 02 Liegt das führende Datenmodell bei euch oder in einem anderen System?
  3. 03 Wie viele Verbindungen stehen wirklich gleichzeitig offen?
  4. 04 Wie lange soll der Dienst laufen und wie viel Pflege bekommt er?
  5. 05 Was von Anmeldung, Rollen, Pflegeoberfläche und Hintergrundarbeit müsstet ihr selbst bauen?
Was du mitnimmst

Was du danach in einer Sitzung entscheidest

Die Wahl hängt an sechs Fragen, die alle vor der ersten Zeile Code beantwortet werden können. Keine davon dreht sich um Anfragen pro Sekunde, und genau das ist der Punkt.

Klären, ob Menschen oder Maschinen zugreifen

Wenn sich Menschen anmelden, Formulare ausfüllen und Daten pflegen sollen, spricht viel für das vollständige Rahmenwerk. Wenn ausschließlich andere Systeme sprechen und die Oberfläche woanders liegt, entfällt der größte Teil dessen, was Django voraushat.

Prüfen, wem die Daten gehören

Liegt das führende Datenmodell in eurem Dienst, dann sind Datenzugriff, Wanderungsskripte und eine Pflegeoberfläche der eigentliche Gewinn. Liegt es in einem anderen System und ihr reicht nur durch, dann ist ein leichtgewichtiger Dienst die passendere Bauform.

Die Betriebsdauer ehrlich einschätzen

Ein Dienst, der fünf Jahre laufen soll und dabei wenig Zuwendung bekommt, profitiert von festen Veröffentlichungszyklen und langen Wartungszeiträumen. Ein Dienst, der in achtzehn Monaten wieder abgelöst wird, verträgt eine schnellere Entwicklungsgeschwindigkeit im Unterbau.

Die Nebenläufigkeit an der echten Last messen

Asynchron gewinnt dort, wo viele Verbindungen gleichzeitig offen stehen und wenig gerechnet wird. Bei einem Dienst mit dreißig gleichzeitigen Anfragen und einer Datenbank dahinter ist der Unterschied Rauschen. Nehmt eure eigene Verteilung als Grundlage, nicht die aus einem fremden Lasttest.

Zusammenzählen, was ihr sonst selbst bauen müsst

Schreibt eine Liste: Anmeldung, Rollen, Schemaänderungen, Verwaltungsoberfläche, Hintergrundaufgaben, Übersetzungen, Schutz vor bekannten Angriffen im Browser. Für jeden Punkt darauf entscheidet ihr, ob er mitgeliefert werden soll oder ob ihr ihn auswählt und pflegt.

Die Mischform ausdrücklich in Betracht ziehen

Beides nebeneinander ist ein üblicher und tragfähiger Aufbau: die fachliche Anwendung mit Datenmodell und Pflege im vollständigen Rahmenwerk, daneben ein schlanker Dienst für eine besonders belastete oder besonders schnelllebige Schnittstelle. Wichtig ist, dass diese Aufteilung eine Entscheidung ist und nicht das Ergebnis persönlicher Vorlieben in zwei Teams.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt

Was in Django tatsächlich schon drin ist

Der Datenzugriff mit eigener Abfragesprache, dazu Wanderungsskripte, die Schemaänderungen aus den Modellklassen ableiten und versioniert im Repository liegen. Benutzer, Gruppen und Rechte samt Anmeldung. Formulare mit Prüfung und Fehlerausgabe. Sitzungen, Schutz vor gefälschten Anfragen aus fremden Seiten, Übersetzungen und Zeitzonenbehandlung. Und die Verwaltungsoberfläche, die aus den Modellen entsteht und in vielen Projekten das interne Werkzeug ist, das die Fachabteilung tatsächlich benutzt.

Mit Version 6.0 sind drei Dinge dazugekommen, die vorher regelmäßig als Argument gegen Django genannt wurden. Es gibt jetzt einen eingebauten Rahmen für Aufgaben außerhalb der Anfrage, also für alles, was bisher zwingend eine zusätzliche Warteschlange verlangt hat. Es gibt Teilvorlagen, mit denen sich wiederverwendbare Bausteine innerhalb einer Vorlagendatei beschreiben lassen. Und es gibt eine eingebaute Unterstützung für Sicherheitsrichtlinien im Browser, die bisher über ein Zusatzpaket lief.

Der Preis für all das ist Struktur. Django gibt eine Aufteilung in Anwendungen vor, eine Reihenfolge beim Verarbeiten von Anfragen und einen bestimmten Umgang mit Einstellungen. Wer das mag, kommt schnell voran, weil jedes Projekt dem nächsten ähnelt. Wer eine ungewöhnliche Bauform braucht, arbeitet an einigen Stellen gegen das Rahmenwerk, und das ist der Punkt, an dem die Alternative interessant wird.

Was FastAPI ist und was daneben stehen muss

FastAPI ist eine dünne, sehr gut durchdachte Schicht über zwei Bibliotheken: einer für den asynchronen Webbetrieb und einer für die Prüfung und Umwandlung von Daten anhand von Typangaben. Daraus ergibt sich die Eigenschaft, für die es bekannt ist: Was in der Signatur der Funktion steht, ist gleichzeitig die Prüfung der Eingabe, die Umwandlung der Ausgabe und die maschinenlesbare Beschreibung der Schnittstelle. Für Dienste, die Verträge mit anderen Teams haben, spart das echte Arbeit und verhindert, dass Dokumentation und Wirklichkeit auseinanderlaufen.

Was nicht enthalten ist, ist ebenso klar. Es gibt keinen Datenzugriff, keine Wanderungsskripte, keine Benutzerverwaltung, keine Oberfläche zur Datenpflege und keinen eingebauten Weg, Arbeit im Hintergrund abzuarbeiten. Für all das gibt es gute Bibliotheken, aber die Auswahl, die Verbindung und die Pflege sind eure Aufgabe. In einem Projekt, das ohnehin nur eine Schnittstelle vor einem fremden System ist, fällt das kaum ins Gewicht. In einem Projekt, das zur Fachanwendung wächst, wird daraus Arbeit, die niemand eingeplant hat.

Bei der Planung lohnt ein Blick auf die Versionslage. Das Projekt steht weiterhin in der Reihe 0.x und veröffentlicht in kurzen Abständen. Für den Betrieb heißt das nicht Instabilität, wohl aber, dass ihr die Fassungen festhalten und die Aktualisierung regelmäßig einplanen solltet, statt einmal im Jahr einen großen Sprung zu versuchen. Dasselbe gilt für die beiden Bibliotheken darunter, deren Entwicklung ihr ohnehin mitverfolgen müsst.

Asynchron ist kein Selbstläufer

Der häufigste Irrtum in dieser Diskussion lautet, ein asynchrones Rahmenwerk sei generell schneller. Es ist genauer gesagt sparsamer bei vielen gleichzeitig offenen Verbindungen, weil eine wartende Anfrage keinen eigenen Ausführungsstrang belegt. Wenn eure Anwendung dreißig Anfragen gleichzeitig bearbeitet und jede davon zwanzig Millisekunden in der Datenbank verbringt, macht die Bauform keinen messbaren Unterschied.

Gefährlich wird es an der Grenze zwischen beiden Welten. Ein blockierender Aufruf innerhalb einer asynchronen Funktion hält den gesamten Event Loop an und bremst damit alle anderen Anfragen mit aus, die auf demselben Worker liegen. Das betrifft Datenbanktreiber ohne asynchrone Unterstützung genauso wie Bibliotheken, die intern eine Datei lesen. FastAPI hat dafür eine sinnvolle Regel: Gewöhnlich definierte Funktionen wandern in einen Thread-Pool, asynchron definierte laufen in der Schleife. Wer diese Unterscheidung falsch trifft, baut sich genau den Engpass, den er vermeiden wollte.

Django geht denselben Weg von der anderen Seite. Anfragen können asynchron behandelt werden, und für einen wachsenden Teil der Schnittstellen gibt es asynchrone Varianten. Der Datenzugriff ist aber in weiten Teilen synchron entstanden, weshalb im gemischten Betrieb Aufrufe ausdrücklich in einen Thread-Pool ausgelagert werden. Das funktioniert zuverlässig und ist gut dokumentiert, der Gewinn bleibt dabei aber kleiner als bei einer durchgehend asynchronen Kette.

Der Mischfall ist häufiger als die Entscheidung

In der Praxis läuft die Frage selten auf ein Entweder-oder hinaus. Ein sehr verbreiteter Aufbau ist eine gewachsene Django-Anwendung mit dem fachlichen Datenmodell und der internen Pflege, daneben ein oder zwei schlanke Dienste für Schnittstellen, die besonders belastet sind oder sich schnell ändern. Beide reden über HTTP miteinander, und dahinter ist das Rahmenwerk gleichgültig.

Der Preis dafür ist real und sollte benannt werden: zwei Werkzeugketten, zwei Abhängigkeitsbäume, zwei Sätze von Basisabbildern und zwei Stellen, an denen Sicherheitsmeldungen auflaufen. Das ist vertretbar, wenn es eine bewusste Entscheidung mit einer klaren Grenze ist. Es ist teuer, wenn es dadurch entstanden ist, dass zwei Teams sich nie abgestimmt haben.

Wer innerhalb von Django bei einer JSON-Schnittstelle bleiben will, hat dafür etablierte Wege, von der klassischen Erweiterung mit eigenen Serialisierern bis zu neueren Paketen, die dieselbe Idee wie FastAPI verfolgen und die Beschreibung der Schnittstelle aus den Typangaben ableiten. Für ein Team, das Django ohnehin einsetzt, ist das häufig die günstigere Antwort als ein zweiter Tech-Stack im Haus.

Dazu passende Kurse

Wenn im Team gerade festgelegt wird, worauf die nächsten Dienste aufsetzen, geben Python-Kurse für die Entwicklung von Diensten dafür die gemeinsame Grundlage.

Weil zu einem Dienst immer auch die Seite gehört, die ihn aufruft, ergänzen Kurse rund um Webanwendungen und Schnittstellen diese Entscheidung.

Wissen prüfen

Wie sicher bist du beim Thema wirklich?

Lesen fühlt sich schnell nach Können an. Ein kurzer Test zeigt dir, was davon schon sitzt und wo sich ein Kurs lohnt. Kostenlos, ohne Anmeldung, mit einer Erklärung zu jeder Antwort.

Sehr umfangreicher Überblick über Zusammenhänge und Anwendungsbereiche. Sehr zu empfehlen.
Einführung in die Programmierung für Programmiereinsteiger
Effektives, gemeinsames Erarbeiten der Aufgaben mit vielen praktischen Tipps.
Groovy Grundkurs
Sehr guter Trainer und gute Aufbereitung der Inhalte und auch eingehen auf Fragen der Beteiligten.
Unreal Engine Kurs für Einsteiger

Häufige Fragen

Ist FastAPI schneller als Django?
Bei vielen gleichzeitig offenen Verbindungen mit wenig Rechenarbeit ja, und das ist messbar. In einer typischen Anfrage mit Datenbankzugriff verschwindet der Unterschied hinter der Datenbankzeit. Verlässlich anders ist vor allem die Bauform: Eine wartende Anfrage belegt keinen eigenen Thread, und das zahlt sich erst bei hoher Gleichzeitigkeit aus.
Können wir mit FastAPI anfangen und später auf Django wechseln?
Technisch ja, praktisch ist es ein Neubau der Datenschicht. Der Datenzugriff, die Wanderungsskripte und die Benutzerverwaltung sind bei Django eng miteinander verzahnt, und genau diese Teile hättet ihr vorher selbst zusammengesetzt. Wenn absehbar ist, dass fachliche Datenpflege dazukommt, ist die Entscheidung besser gleich zu treffen.
Brauchen wir für FastAPI zwingend eine asynchrone Datenbankanbindung?
Nein. Ihr könnt Endpunkte gewöhnlich definieren, dann laufen sie in einem Thread-Pool, und ein synchroner Treiber ist völlig in Ordnung. Falsch wird es erst, wenn ein blockierender Aufruf in einer asynchron definierten Funktion steht, denn dann hält er die Ereignisschleife an und bremst alle anderen Anfragen mit.
Was ist mit der Verwaltungsoberfläche, gibt es das für FastAPI auch?
Es gibt Pakete, die in diese Richtung gehen, sie erreichen aber weder den Umfang noch den Reifegrad dessen, was Django mitbringt. Wenn die Pflege von Stammdaten durch die Fachabteilung ein echtes Thema ist, ist das eines der stärksten Argumente für das vollständige Rahmenwerk, und es wird bei der Entscheidung regelmäßig unterschätzt.
Welche Django-Fassung sollten wir für ein neues Projekt nehmen?
Für ein System mit langer Laufzeit und wenig Pflege die aktuelle Langzeitfassung, also 5.2, die bis April 2028 Sicherheitsaktualisierungen bekommt. Für ein Projekt mit regelmäßiger Zuwendung die aktuelle Fassung, weil ihr damit die neueren Bausteine wie den eingebauten Rahmen für Hintergrundaufgaben nutzen könnt. Die nächste Langzeitfassung ist als 6.2 angekündigt.
Persönlich für dich da

Deine Ansprechpartner

Du bist dir nicht sicher, welcher Kurs oder welches Level zu dir passt? Wir beraten dich persönlich und kostenlos.

Yves Hoppe

Yves Hoppe

Weiterbildung & Beratung

Hilft dir, aus dem Programmierung-Programm den passenden Kurs für deinen Stand zu finden.

Norbert Jansen

Norbert Jansen

Beratung & Inhouse

Plant mit dir Inhouse-Trainings, die auf eure Abläufe und euren Datenbestand zugeschnitten sind.

Beide Wege einmal am eigenen Vorhaben durchspielen

Bei cmt kannst du den Aufbau eines Dienstes mit Django und mit FastAPI nebeneinander üben und siehst dabei, an welchen Stellen euch das vollständige Rahmenwerk Arbeit abnimmt und wo es euch im Weg steht.