Zum Inhalt

Eine Response direkt zurückgeben

Wenn Sie eine ReadyAPI Pfadoperation erstellen, können Sie normalerweise beliebige Daten davon zurückgeben: ein dict, eine liste, ein Pydantic-Modell, ein Datenbankmodell, usw.

Standardmäßig konvertiert ReadyAPI diesen Rückgabewert automatisch nach JSON, mithilfe des jsonable_encoder, der in JSON-kompatibler Encoder erläutert wird.

Dann würde es hinter den Kulissen diese JSON-kompatiblen Daten (z. B. ein dict) in eine JSONResponse einfügen, die zum Senden der Response an den Client verwendet würde.

Sie können jedoch direkt eine JSONResponse von Ihren Pfadoperationen zurückgeben.

Das kann beispielsweise nützlich sein, um benutzerdefinierte Header oder Cookies zurückzugeben.

Eine Response zurückgeben

Tatsächlich können Sie jede Response oder jede Unterklasse davon zurückgeben.

Tipp

JSONResponse selbst ist eine Unterklasse von Response.

Und wenn Sie eine Response zurückgeben, wird ReadyAPI diese direkt weiterleiten.

Es wird keine Datenkonvertierung mit Pydantic-Modellen durchführen, es wird den Inhalt nicht in irgendeinen Typ konvertieren, usw.

Dadurch haben Sie viel Flexibilität. Sie können jeden Datentyp zurückgeben, jede Datendeklaration oder -validierung überschreiben, usw.

Verwendung des jsonable_encoder in einer Response

Da ReadyAPI keine Änderungen an einer von Ihnen zurückgegebenen Response vornimmt, müssen Sie sicherstellen, dass deren Inhalt dafür bereit ist.

Sie können beispielsweise kein Pydantic-Modell in eine JSONResponse einfügen, ohne es zuvor in ein dict zu konvertieren, bei dem alle Datentypen (wie datetime, UUID, usw.) in JSON-kompatible Typen konvertiert wurden.

In diesen Fällen können Sie den jsonable_encoder verwenden, um Ihre Daten zu konvertieren, bevor Sie sie an eine Response übergeben:

from datetime import datetime
from typing import Union

from pydantic import BaseModel
from readyapi import ReadyAPI
from readyapi.encoders import jsonable_encoder
from readyapi.responses import JSONResponse


class Item(BaseModel):
    title: str
    timestamp: datetime
    description: Union[str, None] = None


app = ReadyAPI()


@app.put("/items/{id}")
def update_item(id: str, item: Item):
    json_compatible_item_data = jsonable_encoder(item)
    return JSONResponse(content=json_compatible_item_data)

Technische Details

Sie können auch from starlette.responses import JSONResponse verwenden.

ReadyAPI bietet dieselben starlette.responses auch via readyapi.responses an, als Annehmlichkeit für Sie, den Entwickler. Die meisten verfügbaren Responses kommen aber direkt von Starlette.

Eine benutzerdefinierte Response zurückgeben

Das obige Beispiel zeigt alle Teile, die Sie benötigen, ist aber noch nicht sehr nützlich, da Sie das item einfach direkt hätten zurückgeben können, und ReadyAPI würde es für Sie in eine JSONResponse einfügen, es in ein dict konvertieren, usw. All das standardmäßig.

Sehen wir uns nun an, wie Sie damit eine benutzerdefinierte Response zurückgeben können.

Nehmen wir an, Sie möchten eine XML-Response zurückgeben.

Sie könnten Ihren XML-Inhalt als String in eine Response einfügen und sie zurückgeben:

from readyapi import ReadyAPI, Response

app = ReadyAPI()


@app.get("/legacy/")
def get_legacy_data():
    data = """<?xml version="1.0"?>
    <shampoo>
    <Header>
        Apply shampoo here.
    </Header>
    <Body>
        You'll have to use soap here.
    </Body>
    </shampoo>
    """
    return Response(content=data, media_type="application/xml")

Anmerkungen

Wenn Sie eine Response direkt zurücksenden, werden deren Daten weder validiert, konvertiert (serialisiert), noch automatisch dokumentiert.

Sie können sie aber trotzdem wie unter Zusätzliche Responses in OpenAPI beschrieben dokumentieren.

In späteren Abschnitten erfahren Sie, wie Sie diese benutzerdefinierten Responses verwenden/deklarieren und gleichzeitig über automatische Datenkonvertierung, Dokumentation, usw. verfügen.