fastapi/docs/fr/docs/advanced/openapi-callbacks.md

9.0 KiB
Raw Blame History

Callbacks OpenAPI

Vous pourriez créer une API avec un chemin d'accès qui déclenche une requête vers une API externe créée par quelqu'un d'autre (probablement la même personne développeuse qui utiliserait votre API).

Le processus qui se produit lorsque votre application API appelle lAPI externe sappelle un « callback ». Parce que le logiciel écrit par la personne développeuse externe envoie une requête à votre API puis votre API « rappelle », en envoyant une requête à une API externe (probablement créée par la même personne développeuse).

Dans ce cas, vous pourriez vouloir documenter à quoi cette API externe devrait ressembler. Quel chemin d'accès elle devrait avoir, quel corps elle devrait attendre, quelle réponse elle devrait renvoyer, etc.

Une application avec des callbacks

Voyons tout cela avec un exemple.

Imaginez que vous développiez une application qui permet de créer des factures.

Ces factures auront un id, un title (facultatif), un customer et un total.

Lutilisateur de votre API (une personne développeuse externe) créera une facture dans votre API avec une requête POST.

Ensuite votre API va (imaginons) :

  • Envoyer la facture à un client de la personne développeuse externe.
  • Encaisser largent.
  • Renvoyer une notification à lutilisateur de lAPI (la personne développeuse externe).
    • Cela sera fait en envoyant une requête POST (depuis votre API) vers une API externe fournie par cette personne développeuse externe (cest le « callback »).

Lapplication FastAPI normale

Voyons dabord à quoi ressemble lapplication API normale avant dajouter le callback.

Elle aura un chemin d'accès qui recevra un corps Invoice, et un paramètre de requête callback_url qui contiendra lURL pour le callback.

Cette partie est assez normale, la plupart du code vous est probablement déjà familier :

{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}

/// tip | Astuce

Le paramètre de requête callback_url utilise un type Pydantic Url.

///

La seule nouveauté est callbacks=invoices_callback_router.routes comme argument du décorateur de chemin d'accès. Nous allons voir ce que cest ensuite.

Documenter le callback

Le code réel du callback dépendra fortement de votre application API.

Et il variera probablement beaucoup dune application à lautre.

Cela pourrait être seulement une ou deux lignes de code, comme :

callback_url = "https://example.com/api/v1/invoices/events/"
httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})

Mais la partie la plus importante du callback est sans doute de vous assurer que lutilisateur de votre API (la personne développeuse externe) implémente correctement lAPI externe, conformément aux données que votre API va envoyer dans le corps de la requête du callback, etc.

Ainsi, ce que nous allons faire ensuite, cest ajouter le code pour documenter à quoi cette API externe devrait ressembler pour recevoir le callback de votre API.

Cette documentation apparaîtra dans Swagger UI à /docs dans votre API, et permettra aux personnes développeuses externes de savoir comment construire lAPI externe.

Cet exemple nimplémente pas le callback lui-même (qui pourrait être une simple ligne de code), uniquement la partie documentation.

/// tip | Astuce

Le callback réel nest quune requête HTTP.

En implémentant vous-même le callback, vous pourriez utiliser quelque chose comme HTTPX ou Requests.

///

Écrire le code de documentation du callback

Ce code ne sera pas exécuté dans votre application, nous en avons seulement besoin pour documenter à quoi devrait ressembler cette API externe.

Mais vous savez déjà comment créer facilement une documentation automatique pour une API avec FastAPI.

Nous allons donc utiliser ce même savoir pour documenter à quoi lAPI externe devrait ressembler ... en créant le(s) chemin(s) d'accès que lAPI externe devrait implémenter (ceux que votre API appellera).

/// tip | Astuce

Lorsque vous écrivez le code pour documenter un callback, il peut être utile dimaginer que vous êtes cette personne développeuse externe. Et que vous implémentez actuellement lAPI externe, pas votre API.

Adopter temporairement ce point de vue (celui de la personne développeuse externe) peut vous aider à trouver plus évident où placer les paramètres, le modèle Pydantic pour le corps, pour la réponse, etc., pour cette API externe.

///

Créer un APIRouter de callback

Commencez par créer un nouveau APIRouter qui contiendra un ou plusieurs callbacks.

{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}

Créer le chemin d'accès du callback

Pour créer le chemin d'accès du callback, utilisez le même APIRouter que vous avez créé ci-dessus.

Il devrait ressembler exactement à un chemin d'accès FastAPI normal :

  • Il devrait probablement déclarer le corps quil doit recevoir, par exemple body: InvoiceEvent.
  • Et il pourrait aussi déclarer la réponse quil doit renvoyer, par exemple response_model=InvoiceEventReceived.

{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}

Il y a 2 principales différences par rapport à un chemin d'accès normal :

  • Il na pas besoin davoir de code réel, car votre application nappellera jamais ce code. Il sert uniquement à documenter lAPI externe. La fonction peut donc simplement contenir pass.
  • Le chemin peut contenir une expression OpenAPI 3 (voir plus bas) où il peut utiliser des variables avec des paramètres et des parties de la requête originale envoyée à votre API.

Lexpression du chemin de callback

Le chemin du callback peut contenir une expression OpenAPI 3 qui peut inclure des parties de la requête originale envoyée à votre API.

Dans ce cas, cest la str :

"{$callback_url}/invoices/{$request.body.id}"

Ainsi, si lutilisateur de votre API (la personne développeuse externe) envoie une requête à votre API vers :

https://yourapi.com/invoices/?callback_url=https://www.external.org/events

avec un corps JSON :

{
    "id": "2expen51ve",
    "customer": "Mr. Richie Rich",
    "total": "9999"
}

alors votre API traitera la facture et, à un moment ultérieur, enverra une requête de callback à callback_url (lAPI externe) :

https://www.external.org/events/invoices/2expen51ve

avec un corps JSON contenant quelque chose comme :

{
    "description": "Payment celebration",
    "paid": true
}

et elle sattendra à une réponse de cette API externe avec un corps JSON comme :

{
    "ok": true
}

/// tip | Astuce

Remarquez que lURL de callback utilisée contient lURL reçue en paramètre de requête dans callback_url (https://www.external.org/events) et aussi lid de la facture à lintérieur du corps JSON (2expen51ve).

///

Ajouter le routeur de callback

À ce stade, vous avez le(s) chemin(s) d'accès de callback nécessaire(s) (celui/ceux que la personne développeuse externe doit implémenter dans lAPI externe) dans le routeur de callback que vous avez créé ci-dessus.

Utilisez maintenant le paramètre callbacks dans le décorateur de chemin d'accès de votre API pour passer lattribut .routes (qui est en fait juste une list de routes/chemins d'accès) depuis ce routeur de callback :

{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}

/// tip | Astuce

Remarquez que vous ne passez pas le routeur lui-même (invoices_callback_router) à callback=, mais lattribut .routes, comme dans invoices_callback_router.routes.

///

Vérifier la documentation

Vous pouvez maintenant démarrer votre application et aller sur http://127.0.0.1:8000/docs.

Vous verrez votre documentation incluant une section « Callbacks » pour votre chemin d'accès qui montre à quoi lAPI externe devrait ressembler :