Moderne GraphQL-APIs mit Strawberry auf FastAPI und Django erstellen
Emily Parker
Product Engineer · Leapcell

Einleitung
In der heutigen datengesteuerten Welt sind effizientes und flexibles API-Design von größter Bedeutung. Herkömmliche REST-APIs stoßen zwar auf breite Akzeptanz, stehen aber oft vor Herausforderungen wie Over-Fetching oder Under-Fetching von Daten, was zu einer ineffizienten Kommunikation zwischen Client und Server führt. Hier glänzt GraphQL mit seiner leistungsstarken Abfragesprache für Ihre APIs, die es Clients ermöglicht, genau die Daten anzufordern, die sie benötigen – nicht mehr und nicht weniger. Python ist aufgrund seiner Vielseitigkeit und seines reichen Ökosystems eine beliebte Wahl für die Backend-Entwicklung geworden. Wenn es darum geht, moderne GraphQL-APIs in Python zu erstellen, insbesondere innerhalb von Hochleistungs-Frameworks wie FastAPI oder robusten wie Django, bietet die Strawberry-Bibliothek eine elegante und Python-konforme Lösung. Dieser Artikel befasst sich damit, wie Strawberry die Erstellung anspruchsvoller GraphQL-APIs erleichtert, häufige Fallstricke beim API-Design anspricht und Entwicklern mehr Kontrolle über die Dateninteraktion ermöglicht.
Kernkonzepte erklärt
Bevor wir uns den Implementierungsdetails zuwenden, wollen wir die wichtigsten Konzepte klar verstehen:
- GraphQL: Eine Abfragesprache für Ihre API und eine serverseitige Laufzeitumgebung zur Ausführung von Abfragen anhand eines Typsystems, das Sie für Ihre Daten definieren. Es ist eine Alternative zu REST, die es Clients ermöglicht, spezifische Daten und Schemata anzufordern.
- Strawberry: Eine "code-first" Python GraphQL-Bibliothek. Das bedeutet, dass Sie Ihr GraphQL-Schema direkt in Python-Code mit Standard-Python-Typen und Decorators definieren. Dieser Ansatz führt oft zu einer besseren Entwicklererfahrung und Typsicherheit im Vergleich zu Schema-First-Ansätzen, bei denen Sie die Schema Definition Language (SDL) von GraphQL schreiben und dann Code generieren.
- FastAPI: Ein modernes, schnelles (hoch performantes) Webframework zum Erstellen von APIs mit Python 3.7+ basierend auf Standard-Python-Typ-Hints. Es ist bekannt für seine automatische interaktive API-Dokumentation (Swagger UI/ReDoc) und seine hervorragende Leistung dank Starlette und Pydantic.
- Django: Ein High-Level-Python-Webframework, das schnelle Entwicklung und ein sauberes, pragmatisches Design fördert. Es ist ein "batteries-included"-Framework, das ein ORM, ein Admin-Panel, eine Template-Engine und mehr bietet, was es für komplexe, datenbankgestützte Anwendungen geeignet macht.
- Schema: In GraphQL beschreibt das Schema die Struktur Ihrer Daten und die Operationen, die Clients ausführen können. Es definiert Typen, Felder und ihre Beziehungen.
- Query: Eine Leseoperation in GraphQL. Clients verwenden Queries, um Daten vom Server abzurufen.
- Mutation: Eine Schreiboperation in GraphQL. Clients verwenden Mutationen, um Daten auf dem Server zu ändern (z.B. erstellen, aktualisieren, löschen).
- Resolver: Eine Funktion in GraphQL, die für das Abrufen der Daten für ein bestimmtes Feld im Schema verantwortlich ist. Wenn ein Client ein Feld anfordert, wird der entsprechende Resolver ausgeführt.
GraphQL-APIs mit Strawberry erstellen
Der "code-first"-Ansatz von Strawberry vereinfacht die Schema-Definition, indem er die Python-Typ-Hints nutzt. Dies lässt die Schema-Definition natürlich wirken und integriert sich gut mit IDE-Funktionen wie Autovervollständigung und Typenprüfung.
Prinzip und Implementierung
Strawberry erlaubt es Ihnen, Ihre GraphQL-Typen als Python-Klassen zu definieren, die mit @strawberry.type
dekoriert sind. Felder innerhalb dieser Typen werden als Klassenattribute mit Typ-Hints definiert. Eingabetypen für Mutationen werden ähnlich mit @strawberry.input
definiert.
Die Kernidee ist die Definition einer Query
- und einer Mutation
-Klasse, die als Wurzeltypen Ihres GraphQL-Schemas dienen. Diese Klassen enthalten Methoden (Resolver), die Clients aufrufen können.
Beispiel mit FastAPI
Lassen Sie uns dies anhand eines einfachen Beispiels für die Verwaltung von Büchern veranschaulichen.
Installieren Sie zunächst die notwendigen Bibliotheken:
pip install fastapi "uvicorn[standard]" strawberry-graphql strawberry-graphql-fastapi
Definieren Sie nun Ihr Strawberry-Schema und integrieren Sie es mit FastAPI:
import strawberry from fastapi import FastAPI from strawberry.asgi import GraphQL # In-Memory-Datenbank zur Vereinfachung BOOKS_DB = [] @strawberry.type class Book: id: strawberry.ID title: str author: str year: int @strawberry.input class BookInput: title: str author: str year: int @strawberry.type class Query: @strawberry.field def hello(self) -> str: return "Hello World" @strawberry.field def books(self) -> list[Book]: return BOOKS_DB @strawberry.field def book(self, id: strawberry.ID) -> Book | None: for book in BOOKS_DB: if book.id == id: return book return None @strawberry.type class Mutation: @strawberry.mutation def add_book(self, book_data: BookInput) -> Book: new_book = Book(id=strawberry.ID(str(len(BOOKS_DB) + 1)), **book_data.__dict__) BOOKS_DB.append(new_book) return new_book @strawberry.mutation def update_book(self, id: strawberry.ID, book_data: BookInput) -> Book | None: for i, book in enumerate(BOOKS_DB): if book.id == id: updated_book = Book(id=id, **book_data.__dict__) BOOKS_DB[i] = updated_book return updated_book return None @strawberry.mutation def delete_book(self, id: strawberry.ID) -> bool: global BOOKS_DB initial_len = len(BOOKS_DB) BOOKS_DB = [book for book in BOOKS_DB if book.id != id] return len(BOOKS_DB) < initial_len schema = strawberry.Schema(query=Query, mutation=Mutation) app = FastAPI() app.add_route("/graphql", GraphQL(schema)) # Um dies auszuführen: uvicorn main:app --reload
In diesem FastAPI-Beispiel:
- Wir definieren
Book
als SQLAlchemy-Typ mit@strawberry.type
. Query
undMutation
-Klassen definieren die verfügbaren Operationen.- Jedes Feld innerhalb der
Query
- undMutation
-Klassen ist mit@strawberry.field
bzw.@strawberry.mutation
dekoriert, was es zu GraphQL-exponierten Feldern/Operationen macht. - Typ-Hints sind entscheidend, damit Strawberry die GraphQL-Typen ableiten kann.
GraphQL
ausstrawberry.asgi
wird verwendet, um das Strawberry-Schema in FastAPI zu integrieren.
Sie können dann normalerweise auf das GraphQL-Playground unter http://127.0.0.1:8000/graphql
zugreifen, um Abfragen und Mutationen zu senden.
Beispiel-Query:
query { books { id title author } }
Beispiel-Mutation:
mutation AddNewBook { addBook(bookData: {title: "The Great Gatsby", author: "F. Scott Fitzgerald", year: 1925}) { id title author } }
Beispiel mit Django
Die Integration von Strawberry mit Django ist ebenso unkompliziert und nutzt oft Django-Modelle für Typdefinitionen.
Installieren Sie zunächst die notwendigen Bibliotheken:
pip install django strawberry-graphql "strawberry-graphql-django>=0.9"
Angenommen, Sie haben bereits ein Django-Projekt und eine App namens books
. Definieren Sie ein Book
-Modell:
# books/models.py from django.db import models class Book(models.Model): title = models.CharField(max_length=200) author = models.CharField(max_length=200) year = models.IntegerField() def __name__(self): return self.title
Definieren Sie nun Ihr Strawberry-Schema in einer Datei wie books/schema.py
:
# books/schema.py import strawberry from strawberry_django.views import GraphQLView from .models import Book # Verwendung von strawberry_django zur automatischen Generierung von Typen aus Django-Modellen @strawberry.django.type(Book) class BookType: id: strawberry.ID title: str author: str year: int @strawberry.input class BookInput: title: str author: str year: int @strawberry.type class Query: @strawberry.field def hello(self) -> str: return "Hello from Django!" @strawberry.field def books(self) -> list[BookType]: return Book.objects.all() @strawberry.field def book(self, id: strawberry.ID) -> BookType | None: try: return Book.objects.get(pk=id) except Book.DoesNotExist: return None @strawberry.type class Mutation: @strawberry.mutation def add_book(self, book_data: BookInput) -> BookType: new_book = Book.objects.create(**book_data.__dict__) return new_book @strawberry.mutation def update_book(self, id: strawberry.ID, book_data: BookInput) -> BookType | None: try: book_to_update = Book.objects.get(pk=id) for key, value in book_data.__dict__.items(): setattr(book_to_update, key, value) book_to_update.save() return book_to_update except Book.DoesNotExist: return None @strawberry.mutation def delete_book(self, id: strawberry.ID) -> bool: try: book_to_delete = Book.objects.get(pk=id) book_to_delete.delete() return True except Book.DoesNotExist: return False schema = strawberry.Schema(query=Query, mutation=Mutation)
Konfigurieren Sie schließlich Ihre Django urls.py
, um den GraphQL-Endpunkt bereitzustellen:
# myproject/urls.py (oder Ihre App-urls.py) from django.contrib import admin from django.urls import path from strawberry_django.views import GraphQLView from books.schema import schema urlpatterns = [ path("admin/", admin.site.urls), path("graphql", GraphQLView.as_view(schema=schema)), ]
Um die Django-Anwendung auszuführen:
python manage.py makemigrations books python manage.py migrate python manage.py runserver
Die Django-Integration profitiert von strawberry-graphql-django
, das Hilfsfunktionen wie @strawberry.django.type
bietet, um Django-Modelle automatisch GraphQL-Typen zuzuordnen und Boilerplate-Code zu reduzieren.
Anwendungsszenarien
- Single-Page Applications (SPAs) und mobile Apps: GraphQL ist ideal für diese Anwendungen, da es ihnen ermöglicht, alle benötigten Daten in einer einzigen Anfrage abzurufen, wodurch Netzwerk-Roundtrips reduziert und die Leistung verbessert wird.
- Microservices-Architektur: GraphQL kann als API-Gateway fungieren, Daten von verschiedenen Microservices aggregieren und eine einheitliche API für Clients bereitstellen.
- Öffentliche APIs: Das Anbieten eines GraphQL-Endpunkts neben oder anstelle von REST kann den Konsumenten mehr Flexibilität und Kontrolle über die Daten geben, die sie erhalten.
- Echtzeitdaten: Strawberry unterstützt Abonnements, die Echtzeit-Datenaktualisierungen über WebSockets ermöglichen und sich für Chat-Anwendungen, Live-Dashboards oder Benachrichtigungen eignen.
Fazit
Strawberry bietet eine höchst Python-konforme und effiziente Methode zum Erstellen robuster GraphQL-APIs, die nahtlos in beliebte Frameworks wie FastAPI und Django integriert werden können. Sein code-first-Ansatz, die starke Typ-Hinting-Unterstützung und der exzellente Community-Support befähigen Entwickler, flexible und performante Datenabrufschichten zu erstellen. Durch die Nutzung von Strawberry können Entwickler die Einschränkungen traditioneller REST-APIs überwinden und den Clients präzise Datenabruffunktionen bieten, während sie gleichzeitig eine saubere und wartbare Backend-Codebasis aufrechterhalten. Letztendlich hilft Strawberry dabei, zukunftssichere APIs zu erstellen, die sowohl leistungsstark als auch angenehm zu verwenden sind.