diff --git a/docs/de/docs/tutorial/dependencies/index.md b/docs/de/docs/tutorial/dependencies/index.md new file mode 100644 index 000000000..6254e976d --- /dev/null +++ b/docs/de/docs/tutorial/dependencies/index.md @@ -0,0 +1,352 @@ +# Abhängigkeiten + +**FastAPI** hat ein sehr mächtiges, aber intuitives **Dependency Injection** System. + +Es ist so konzipiert, sehr einfach zu verwenden zu sein und es jedem Entwickler sehr leicht zu machen, andere Komponenten mit **FastAPI** zu integrieren. + +## Was ist „Dependency Injection“ + +**„Dependency Injection“** bedeutet in der Programmierung, dass es für Ihren Code (in diesem Fall Ihre *Pfadoperation-Funktionen*) eine Möglichkeit gibt, Dinge zu deklarieren, die er verwenden möchte und die er zum Funktionieren benötigt: „Abhängigkeiten“ – „Dependencies“. + +Das System (in diesem Fall **FastAPI**) kümmert sich dann darum, Ihren Code mit den erforderlichen Abhängigkeiten zu versorgen („die Abhängigkeiten einfügen“ – „inject the dependencies“). + +Das ist sehr nützlich, wenn Sie: + +* Eine gemeinsame Logik haben (die gleiche Code-Logik immer und immer wieder). +* Datenbankverbindungen teilen. +* Sicherheit, Authentifizierung, Rollenanforderungen, usw. durchsetzen. +* Und viele andere Dinge ... + +All dies, während Sie Codeverdoppelung minimieren. + +## Erste Schritte + +Sehen wir uns ein sehr einfaches Beispiel an. Es ist so einfach, dass es vorerst nicht sehr nützlich ist. + +Aber so können wir uns besser auf die Funktionsweise des **Dependency Injection** Systems konzentrieren. + +### Erstellen Sie eine Abhängigkeit („Dependable“) + +Konzentrieren wir uns zunächst auf die Abhängigkeit - die Dependency. + +Es handelt sich einfach um eine Funktion, die die gleichen Parameter entgegennimmt wie eine *Pfadoperation-Funktion*: +=== "Python 3.10+" + + ```Python hl_lines="8-9" + {!> ../../../docs_src/dependencies/tutorial001_an_py310.py!} + ``` + +=== "Python 3.9+" + + ```Python hl_lines="8-11" + {!> ../../../docs_src/dependencies/tutorial001_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="9-12" + {!> ../../../docs_src/dependencies/tutorial001_an.py!} + ``` + +=== "Python 3.10+ nicht annotiert" + + !!! tip "Tipp" + Bevorzugen Sie die `Annotated`-Version, falls möglich. + + ```Python hl_lines="6-7" + {!> ../../../docs_src/dependencies/tutorial001_py310.py!} + ``` + +=== "Python 3.8+ nicht annotiert" + + !!! tip "Tipp" + Bevorzugen Sie die `Annotated`-Version, falls möglich. + + ```Python hl_lines="8-11" + {!> ../../../docs_src/dependencies/tutorial001.py!} + ``` + +Das war's schon. + +**Zwei Zeilen**. + +Und sie hat die gleiche Form und Struktur wie alle Ihre *Pfadoperation-Funktionen*. + +Sie können sie sich als *Pfadoperation-Funktion* ohne den „Dekorator“ (ohne `@app.get("/some-path")`) vorstellen. + +Und sie kann alles zurückgeben, was Sie möchten. + +In diesem Fall erwartet diese Abhängigkeit: + +* Einen optionalen Query-Parameter `q`, der ein `str` ist. +* Einen optionalen Query-Parameter `skip`, der ein `int` ist und standardmäßig `0` ist. +* Einen optionalen Query-Parameter `limit`, der ein `int` ist und standardmäßig `100` ist. + +Und dann wird einfach ein `dict` zurückgegeben, welches diese Werte enthält. + +!!! info + FastAPI unterstützt (und empfiehlt die Verwendung von) `Annotated` seit Version 0.95.0. + + Wenn Sie eine ältere Version haben, werden Sie Fehler angezeigt bekommen, wenn Sie versuchen, `Annotated` zu verwenden. + + Bitte [aktualisieren Sie FastAPI](../../deployment/versions.md#upgrade-der-fastapi-versionen){.internal-link target=_blank} daher mindestens zu Version 0.95.1, bevor Sie `Annotated` verwenden. + +### `Depends` importieren + +=== "Python 3.10+" + + ```Python hl_lines="3" + {!> ../../../docs_src/dependencies/tutorial001_an_py310.py!} + ``` + +=== "Python 3.9+" + + ```Python hl_lines="3" + {!> ../../../docs_src/dependencies/tutorial001_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="3" + {!> ../../../docs_src/dependencies/tutorial001_an.py!} + ``` + +=== "Python 3.10+ nicht annotiert" + + !!! tip "Tipp" + Bevorzugen Sie die `Annotated`-Version, falls möglich. + + ```Python hl_lines="1" + {!> ../../../docs_src/dependencies/tutorial001_py310.py!} + ``` + +=== "Python 3.8+ nicht annotiert" + + !!! tip "Tipp" + Bevorzugen Sie die `Annotated`-Version, falls möglich. + + ```Python hl_lines="3" + {!> ../../../docs_src/dependencies/tutorial001.py!} + ``` + +### Deklarieren der Abhängigkeit im „Dependant“ + +So wie auch `Body`, `Query`, usw., verwenden Sie `Depends` mit den Parametern Ihrer *Pfadoperation-Funktion*: + +=== "Python 3.10+" + + ```Python hl_lines="13 18" + {!> ../../../docs_src/dependencies/tutorial001_an_py310.py!} + ``` + +=== "Python 3.9+" + + ```Python hl_lines="15 20" + {!> ../../../docs_src/dependencies/tutorial001_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="16 21" + {!> ../../../docs_src/dependencies/tutorial001_an.py!} + ``` + +=== "Python 3.10+ nicht annotiert" + + !!! tip "Tipp" + Bevorzugen Sie die `Annotated`-Version, falls möglich. + + ```Python hl_lines="11 16" + {!> ../../../docs_src/dependencies/tutorial001_py310.py!} + ``` + +=== "Python 3.8+ nicht annotiert" + + !!! tip "Tipp" + Bevorzugen Sie die `Annotated`-Version, falls möglich. + + ```Python hl_lines="15 20" + {!> ../../../docs_src/dependencies/tutorial001.py!} + ``` + +Obwohl Sie `Depends` in den Parametern Ihrer Funktion genauso verwenden wie `Body`, `Query`, usw., funktioniert `Depends` etwas anders. + +Sie übergeben `Depends` nur einen einzigen Parameter. + +Dieser Parameter muss so etwas wie eine Funktion sein. + +Sie **rufen diese nicht direkt auf** (fügen Sie am Ende keine Klammern hinzu), sondern übergeben sie einfach als Parameter an `Depends()`. + +Und diese Funktion akzeptiert Parameter auf die gleiche Weise wie *Pfadoperation-Funktionen*. + +!!! tip "Tipp" + Im nächsten Kapitel erfahren Sie, welche anderen „Dinge“, außer Funktionen, Sie als Abhängigkeiten verwenden können. + +Immer wenn ein neuer Request eintrifft, kümmert sich **FastAPI** darum: + +* Ihre Abhängigkeitsfunktion („Dependable“) mit den richtigen Parametern aufzurufen. +* Sich das Ergebnis von dieser Funktion zu holen. +* Dieses Ergebnis dem Parameter Ihrer *Pfadoperation-Funktion* zuzuweisen. + +```mermaid +graph TB + +common_parameters(["common_parameters"]) +read_items["/items/"] +read_users["/users/"] + +common_parameters --> read_items +common_parameters --> read_users +``` + +Auf diese Weise schreiben Sie gemeinsam genutzten Code nur einmal, und **FastAPI** kümmert sich darum, ihn für Ihre *Pfadoperationen* aufzurufen. + +!!! check + Beachten Sie, dass Sie keine spezielle Klasse erstellen und diese irgendwo an **FastAPI** übergeben müssen, um sie zu „registrieren“ oder so ähnlich. + + Sie übergeben es einfach an `Depends` und **FastAPI** weiß, wie der Rest erledigt wird. + +## `Annotated`-Abhängigkeiten wiederverwenden + +In den Beispielen oben sehen Sie, dass es ein kleines bisschen **Codeverdoppelung** gibt. + +Wenn Sie die Abhängigkeit `common_parameters()` verwenden, müssen Sie den gesamten Parameter mit der Typannotation und `Depends()` schreiben: + +```Python +commons: Annotated[dict, Depends(common_parameters)] +``` + +Da wir jedoch `Annotated` verwenden, können wir diesen `Annotated`-Wert in einer Variablen speichern und an mehreren Stellen verwenden: + +=== "Python 3.10+" + + ```Python hl_lines="12 16 21" + {!> ../../../docs_src/dependencies/tutorial001_02_an_py310.py!} + ``` + +=== "Python 3.9+" + + ```Python hl_lines="14 18 23" + {!> ../../../docs_src/dependencies/tutorial001_02_an_py39.py!} + ``` + +=== "Python 3.8+" + + ```Python hl_lines="15 19 24" + {!> ../../../docs_src/dependencies/tutorial001_02_an.py!} + ``` + +!!! tip "Tipp" + Das ist schlicht Standard-Python, es wird als „Typalias“ bezeichnet und ist eigentlich nicht **FastAPI**-spezifisch. + + Da **FastAPI** jedoch auf Standard-Python, einschließlich `Annotated`, basiert, können Sie diesen Trick in Ihrem Code verwenden. 😎 + +Die Abhängigkeiten funktionieren weiterhin wie erwartet, und das **Beste daran** ist, dass die **Typinformationen erhalten bleiben**, was bedeutet, dass Ihr Editor Ihnen weiterhin **automatische Vervollständigung**, **Inline-Fehler**, usw. bieten kann. Das Gleiche gilt für andere Tools wie `mypy`. + +Das ist besonders nützlich, wenn Sie es in einer **großen Codebasis** verwenden, in der Sie in **vielen *Pfadoperationen*** immer wieder **dieselben Abhängigkeiten** verwenden. + +## `async` oder nicht `async` + +Da Abhängigkeiten auch von **FastAPI** aufgerufen werden (so wie Ihre *Pfadoperation-Funktionen*), gelten beim Definieren Ihrer Funktionen die gleichen Regeln. + +Sie können `async def` oder einfach `def` verwenden. + +Und Sie können Abhängigkeiten mit `async def` innerhalb normaler `def`-*Pfadoperation-Funktionen* oder `def`-Abhängigkeiten innerhalb von `async def`-*Pfadoperation-Funktionen*, usw. deklarieren. + +Es spielt keine Rolle. **FastAPI** weiß, was zu tun ist. + +!!! note "Hinweis" + Wenn Ihnen das nichts sagt, lesen Sie den [Async: *„In Eile?“*](../../async.md#in-eile){.internal-link target=_blank}-Abschnitt über `async` und `await` in der Dokumentation. + +## Integriert in OpenAPI + +Alle Requestdeklarationen, -validierungen und -anforderungen Ihrer Abhängigkeiten (und Unterabhängigkeiten) werden in dasselbe OpenAPI-Schema integriert. + +Die interaktive Dokumentation enthält also auch alle Informationen aus diesen Abhängigkeiten: + + + +## Einfache Verwendung + +Näher betrachtet, werden *Pfadoperation-Funktionen* deklariert, um verwendet zu werden, wann immer ein *Pfad* und eine *Operation* übereinstimmen, und dann kümmert sich **FastAPI** darum, die Funktion mit den richtigen Parametern aufzurufen, die Daten aus der Anfrage extrahierend. + +Tatsächlich funktionieren alle (oder die meisten) Webframeworks auf die gleiche Weise. + +Sie rufen diese Funktionen niemals direkt auf. Sie werden von Ihrem Framework aufgerufen (in diesem Fall **FastAPI**). + +Mit dem Dependency Injection System können Sie **FastAPI** ebenfalls mitteilen, dass Ihre *Pfadoperation-Funktion* von etwas anderem „abhängt“, das vor Ihrer *Pfadoperation-Funktion* ausgeführt werden soll, und **FastAPI** kümmert sich darum, es auszuführen und die Ergebnisse zu „injizieren“. + +Andere gebräuchliche Begriffe für dieselbe Idee der „Abhängigkeitsinjektion“ sind: + +* Ressourcen +* Provider +* Services +* Injectables +* Komponenten + +## **FastAPI**-Plugins + +Integrationen und „Plugins“ können mit dem **Dependency Injection** System erstellt werden. Aber tatsächlich besteht **keine Notwendigkeit, „Plugins“ zu erstellen**, da es durch die Verwendung von Abhängigkeiten möglich ist, eine unendliche Anzahl von Integrationen und Interaktionen zu deklarieren, die dann für Ihre *Pfadoperation-Funktionen* verfügbar sind. + +Und Abhängigkeiten können auf sehr einfache und intuitive Weise erstellt werden, sodass Sie einfach die benötigten Python-Packages importieren und sie in wenigen Codezeilen, *im wahrsten Sinne des Wortes*, mit Ihren API-Funktionen integrieren. + +Beispiele hierfür finden Sie in den nächsten Kapiteln zu relationalen und NoSQL-Datenbanken, Sicherheit usw. + +## **FastAPI**-Kompatibilität + +Die Einfachheit des Dependency Injection Systems macht **FastAPI** kompatibel mit: + +* allen relationalen Datenbanken +* NoSQL-Datenbanken +* externen Packages +* externen APIs +* Authentifizierungs- und Autorisierungssystemen +* API-Nutzungs-Überwachungssystemen +* Responsedaten-Injektionssystemen +* usw. + +## Einfach und leistungsstark + +Obwohl das hierarchische Dependency Injection System sehr einfach zu definieren und zu verwenden ist, ist es dennoch sehr mächtig. + +Sie können Abhängigkeiten definieren, die selbst wiederum Abhängigkeiten definieren können. + +Am Ende wird ein hierarchischer Baum von Abhängigkeiten erstellt, und das **Dependency Injection** System kümmert sich darum, alle diese Abhängigkeiten (und deren Unterabhängigkeiten) für Sie aufzulösen und die Ergebnisse bei jedem Schritt einzubinden (zu injizieren). + +Nehmen wir zum Beispiel an, Sie haben vier API-Endpunkte (*Pfadoperationen*): + +* `/items/public/` +* `/items/private/` +* `/users/{user_id}/activate` +* `/items/pro/` + +Dann könnten Sie für jeden davon unterschiedliche Berechtigungsanforderungen hinzufügen, nur mit Abhängigkeiten und Unterabhängigkeiten: + +```mermaid +graph TB + +current_user(["current_user"]) +active_user(["active_user"]) +admin_user(["admin_user"]) +paying_user(["paying_user"]) + +public["/items/public/"] +private["/items/private/"] +activate_user["/users/{user_id}/activate"] +pro_items["/items/pro/"] + +current_user --> active_user +active_user --> admin_user +active_user --> paying_user + +current_user --> public +active_user --> private +admin_user --> activate_user +paying_user --> pro_items +``` + +## Integriert mit **OpenAPI** + +Alle diese Abhängigkeiten, während sie ihre Anforderungen deklarieren, fügen auch Parameter, Validierungen, usw. zu Ihren *Pfadoperationen* hinzu. + +**FastAPI** kümmert sich darum, alles zum OpenAPI-Schema hinzuzufügen, damit es in den interaktiven Dokumentationssystemen angezeigt wird.