Codes HTTP supplémentaires¶
Par défaut, ReadyAPI renverra les réponses à l'aide d'une structure de données JSONResponse, en plaçant la réponse de votre chemin d'accès à l'intérieur de cette JSONResponse.
Il utilisera le code HTTP par défaut ou celui que vous avez défini dans votre chemin d'accès.
Codes HTTP supplémentaires¶
Si vous souhaitez renvoyer des codes HTTP supplémentaires en plus du code principal, vous pouvez le faire en renvoyant directement une Response, comme une JSONResponse, et en définissant directement le code HTTP supplémentaire.
Par exemple, disons que vous voulez avoir un chemin d'accès qui permet de mettre à jour les éléments et renvoie les codes HTTP 200 "OK" en cas de succès.
Mais vous voulez aussi qu'il accepte de nouveaux éléments. Et lorsque les éléments n'existaient pas auparavant, il les crée et renvoie un code HTTP de 201 "Créé".
Pour y parvenir, importez JSONResponse et renvoyez-y directement votre contenu, en définissant le status_code que vous souhaitez :
from typing import Union
from readyapi import Body, ReadyAPI, status
from readyapi.responses import JSONResponse
app = ReadyAPI()
items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
@app.put("/items/{item_id}")
async def upsert_item(
item_id: str,
name: Union[str, None] = Body(default=None),
size: Union[int, None] = Body(default=None),
):
if item_id in items:
item = items[item_id]
item["name"] = name
item["size"] = size
return item
else:
item = {"name": name, "size": size}
items[item_id] = item
return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
🤓 Other versions and variants
from typing import Annotated
from readyapi import Body, ReadyAPI, status
from readyapi.responses import JSONResponse
app = ReadyAPI()
items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
@app.put("/items/{item_id}")
async def upsert_item(
item_id: str,
name: Annotated[str | None, Body()] = None,
size: Annotated[int | None, Body()] = None,
):
if item_id in items:
item = items[item_id]
item["name"] = name
item["size"] = size
return item
else:
item = {"name": name, "size": size}
items[item_id] = item
return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
from typing import Annotated, Union
from readyapi import Body, ReadyAPI, status
from readyapi.responses import JSONResponse
app = ReadyAPI()
items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
@app.put("/items/{item_id}")
async def upsert_item(
item_id: str,
name: Annotated[Union[str, None], Body()] = None,
size: Annotated[Union[int, None], Body()] = None,
):
if item_id in items:
item = items[item_id]
item["name"] = name
item["size"] = size
return item
else:
item = {"name": name, "size": size}
items[item_id] = item
return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
from typing import Union
from readyapi import Body, ReadyAPI, status
from readyapi.responses import JSONResponse
from typing_extensions import Annotated
app = ReadyAPI()
items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
@app.put("/items/{item_id}")
async def upsert_item(
item_id: str,
name: Annotated[Union[str, None], Body()] = None,
size: Annotated[Union[int, None], Body()] = None,
):
if item_id in items:
item = items[item_id]
item["name"] = name
item["size"] = size
return item
else:
item = {"name": name, "size": size}
items[item_id] = item
return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
Tip
Prefer to use the Annotated version if possible.
from readyapi import Body, ReadyAPI, status
from readyapi.responses import JSONResponse
app = ReadyAPI()
items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
@app.put("/items/{item_id}")
async def upsert_item(
item_id: str,
name: str | None = Body(default=None),
size: int | None = Body(default=None),
):
if item_id in items:
item = items[item_id]
item["name"] = name
item["size"] = size
return item
else:
item = {"name": name, "size": size}
items[item_id] = item
return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
Attention
Lorsque vous renvoyez une Response directement, comme dans l'exemple ci-dessus, elle sera renvoyée directement.
Elle ne sera pas sérialisée avec un modèle.
Assurez-vous qu'il contient les données souhaitées et que les valeurs soient dans un format JSON valides (si vous utilisez une JSONResponse).
Détails techniques
Vous pouvez également utiliser from starlette.responses import JSONResponse.
Pour plus de commodités, ReadyAPI fournit les objets starlette.responses sous forme d'un alias accessible par readyapi.responses. Mais la plupart des réponses disponibles proviennent directement de Starlette. Il en est de même avec l'objet statut.
Documents OpenAPI et API¶
Si vous renvoyez directement des codes HTTP et des réponses supplémentaires, ils ne seront pas inclus dans le schéma OpenAPI (la documentation de l'API), car ReadyAPI n'a aucun moyen de savoir à l'avance ce que vous allez renvoyer.
Mais vous pouvez documenter cela dans votre code, en utilisant : Réponses supplémentaires dans OpenAPI.