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
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
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
| Entscheidungsfrage | Django | FastAPI |
|---|---|---|
| Wie schnell steht ein Dienst mit Datenbank, Anmeldung und Datenpflege? | Stärke 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. | Schwäche 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? | Kommt darauf an 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. | Stärke 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? | Kommt darauf an 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. | Stärke 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? | Stärke 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. | Kommt darauf an 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? | Stärke 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. | Schwäche 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? | Kommt darauf an 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. | Stärke 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. |
Wie schnell steht ein Dienst mit Datenbank, Anmeldung und Datenpflege?
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.
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?
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.
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 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.
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?
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.
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?
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.
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?
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.
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
- 01 Melden sich Menschen an und pflegen Daten? Dann zählt der mitgelieferte Umfang.
- 02 Liegt das führende Datenmodell bei euch oder in einem anderen System?
- 03 Wie viele Verbindungen stehen wirklich gleichzeitig offen?
- 04 Wie lange soll der Dienst laufen und wie viel Pflege bekommt er?
- 05 Was von Anmeldung, Rollen, Pflegeoberfläche und Hintergrundarbeit müsstet ihr selbst bauen?
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.
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.
Wo du genau das übst
Sehr umfangreicher Überblick über Zusammenhänge und Anwendungsbereiche. Sehr zu empfehlen.
Effektives, gemeinsames Erarbeiten der Aufgaben mit vielen praktischen Tipps.
Sehr guter Trainer und gute Aufbereitung der Inhalte und auch eingehen auf Fragen der Beteiligten.
Häufige Fragen
Ist FastAPI schneller als Django?
Können wir mit FastAPI anfangen und später auf Django wechseln?
Brauchen wir für FastAPI zwingend eine asynchrone Datenbankanbindung?
Was ist mit der Verwaltungsoberfläche, gibt es das für FastAPI auch?
Welche Django-Fassung sollten wir für ein neues Projekt nehmen?
Deine Ansprechpartner
Du bist dir nicht sicher, welcher Kurs oder welches Level zu dir passt? Wir beraten dich persönlich und kostenlos.
Yves Hoppe
Weiterbildung & Beratung
Hilft dir, aus dem Programmierung-Programm den passenden Kurs für deinen Stand zu finden.
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.