Skip to content

Chapitre 3.4 : Opérations CRUD pour les vaisseaux spatiaux

Temps d'étude : 1 heure


1. CRUD : Cycle complet de gestion de mission spatiale

Jusqu'à présent, nous n'avons fait que lire des données (Read). Mais un véritable Centre de Contrôle de Mission doit tout savoir faire :

  • Create (Créer) : Lancer un nouveau satellite en orbite.
  • Read (Lire) : Demander le statut d'un vaisseau existant.
  • Update (Mettre à jour) : Corriger l'orbite ou mettre à jour le logiciel.
  • Delete (Supprimer) : Désorbiter un ancien satellite.

Ces quatre opérations — CRUD — constituent la base de la plupart des API. Dans ce chapitre, nous allons implémenter le cycle complet pour gérer notre flotte.


2. Create : Lancement d'un nouveau vaisseau (POST)

Pour créer un nouveau vaisseau spatial, nous utiliserons la méthode POST. Les données du nouveau vaisseau seront transmises dans le corps de la requête au format JSON.

Étape 1 : Créer un nouveau modèle Pydantic pour les données entrantes Pourquoi un nouveau modèle est-il nécessaire ? Parce que lors de la création d'un vaisseau, nous ne connaissons pas son id – il doit être attribué par le serveur.

Ajoutez ce modèle à main.py :

# main.py
from pydantic import BaseModel, Field

class SpaceshipCreate(BaseModel):
    """Modèle pour créer un nouveau vaisseau (sans ID)."""
    name: str = Field(..., min_length=3, max_length=50)
    type: str
    launch_year: int = Field(..., gt=1950)
    status: str
Ce modèle est presque identique à Spaceship, mais il sera utilisé pour la validation des données entrantes.

Étape 2 : Implémenter le point d'accès POST /spaceships

# main.py
import random # Ajoutez cet import en haut du fichier

# ... остальной код ...

@app.post("/spaceships", response_model=Spaceship, status_code=201)
def create_spaceship(ship: SpaceshipCreate):
    """
    Ajoute un nouveau vaisseau spatial au registre.
    """
    # Générer un nouvel ID unique pour le vaisseau
    new_id = max(db_spaceships.keys() or [0]) + 1

    # Créer un objet vaisseau correspondant au modèle Spaceship complet
    new_ship = Spaceship(id=new_id, **ship.dict())

    # Sauvegarder dans notre "base de données"
    db_spaceships[new_id] = new_ship.dict()

    return new_ship
Explication :

  • @app.post(...) : Utilise le décorateur pour les requêtes POST.
  • status_code=201 : Indique qu'un statut 201 Created doit être renvoyé en cas de création réussie.
  • ship: SpaceshipCreate : Voici la magie ! FastAPI prendra automatiquement le corps de la requête (JSON), le validera selon le modèle SpaceshipCreate et le passera à la fonction comme un objet ship.
  • new_id = ... : Logique simple pour générer un nouvel ID.
  • **ship.dict() : Nous "déballons" les données du modèle ship reçu dans notre modèle complet.
  • response_model=Spaceship : La réponse correspondra au modèle complet, incluant l'id.

3. Update : Correction de cap (PUT)

La méthode PUT est utilisée pour la mise à jour complète d'une ressource existante.

Implémenter le point d'accès PUT /spaceships/{ship_id} :

# main.py
from fastapi import FastAPI, HTTPException # Mettez à jour l'import

# ... остальной код ...

@app.put("/spaceships/{ship_id}", response_model=Spaceship)
def update_spaceship(ship_id: int, ship_update: SpaceshipCreate):
    """
    Met à jour complètement les données d'un vaisseau spatial.
    """
    if ship_id not in db_spaceships:
        raise HTTPException(status_code=404, detail="Vaisseau spatial non trouvé")

    updated_ship = Spaceship(id=ship_id, **ship_update.dict())
    db_spaceships[ship_id] = updated_ship.dict()

    return updated_ship

  • ship_update: SpaceshipCreate : Nous utilisons à nouveau notre modèle pour la validation des données entrantes.
  • HTTPException : Si le vaisseau avec cet id n'est pas trouvé, nous "levons" une exception FastAPI standard, qui se transformera en une belle réponse JSON avec le code 404.

4. Delete : Désorbitation (DELETE)

La méthode DELETE est utilisée pour supprimer une ressource. Habituellement, ce point d'accès ne renvoie pas de corps de réponse.

Implémenter le point d'accès DELETE /spaceships/{ship_id} :

# main.py
from fastapi import FastAPI, HTTPException, Response, status # Mettez à jour l'import

# ... остальной код ...

@app.delete("/spaceships/{ship_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_spaceship(ship_id: int):
    """
    Supprime un vaisseau spatial du registre.
    """
    if ship_id not in db_spaceships:
        raise HTTPException(status_code=404, detail="Vaisseau spatial non trouvé")

    del db_spaceships[ship_id]

    # Retourne une réponse vide avec le statut 204
    return Response(status_code=status.HTTP_204_NO_CONTENT)

  • status_code=status.HTTP_204_NO_CONTENT : Nous indiquons explicitement le statut 204 No Content.
  • del db_spaceships[ship_id] : Supprime l'entrée de notre dictionnaire.
  • return Response(...) : Retourne une réponse vide, car le client n'a pas besoin de données sur l'objet supprimé.

5. Test du cycle complet dans /docs

Votre uvicorn devrait s'être rechargé.

  1. Ouvrez http://127.0.0.1:8000/docs. Vous disposez maintenant d'un ensemble complet d'opérations CRUD !
  2. POST : Développez le point d'accès POST /spaceships, cliquez sur "Try it out", remplissez le corps JSON (par exemple, créez le "James Webb Telescope") et cliquez sur "Execute". Vous devriez recevoir une réponse 201 avec les données du nouveau télescope.
  3. GET : Exécutez maintenant GET /spaceships. Votre nouveau télescope devrait apparaître dans la liste.
  4. PUT : Utilisez l'ID du nouveau télescope pour mettre à jour ses données via PUT /spaceships/{ship_id}. Par exemple, modifiez son statut.
  5. DELETE : Utilisez le même ID pour supprimer le télescope via DELETE /spaceships/{ship_id}. Vous devriez recevoir une réponse vide avec le statut 204.
  6. Vérification : Exécutez à nouveau GET /spaceships pour vous assurer que le télescope a été supprimé de la liste.

Quiz pour la consolidation

1. Quelle méthode HTTP est utilisée pour créer une nouvelle ressource ?

2. Le code de statut de succès standard pour une opération `DELETE` :

3. Comment FastAPI reçoit-il les données du corps d'une requête POST ?

4. `raise HTTPException(status_code=404)` est utilisé pour :

5. Pourquoi avons-nous créé un modèle `SpaceshipCreate` séparé pour la création de ressources (`POST`) ?


🚀 Résumé du chapitre :

Vous avez implémenté un cycle CRUD complet et transformé votre API d'un simple "tableau d'information" en un véritable Centre de Contrôle de Flotte !

  • Create : POST /spaceships pour lancer de nouveaux vaisseaux.
  • Read : GET /spaceships et GET /spaceships/{id} pour obtenir les données.
  • Update : PUT /spaceships/{id} pour mettre à jour les missions.
  • Delete : DELETE /spaceships/{id} pour désorbiter les vaisseaux.

Votre flotte est sous contrôle total ! Dans le prochain chapitre, nous verrons comment FastAPI a automatiquement créé pour nous un "manuel d'utilisation" détaillé – la documentation interactive Swagger.

📌 Vérification :

  • Les 5 points d'accès (GET (2), POST, PUT, DELETE) sont visibles et fonctionnent dans /docs.
  • Vous pouvez créer, lire, mettre à jour et supprimer une ressource avec succès.
  • Lors d'une requête avec un ID inexistant, une erreur 404 est renvoyée.

⚠️ En cas d'erreurs :

  • NameError : Vérifiez que vous avez importé HTTPException, Response, status.
  • KeyError : Il est probable que vous essayiez d'accéder à un ID déjà supprimé.
  • Fonctionnement incorrect de PUT ou POST : Assurez-vous d'utiliser le bon modèle Pydantic dans l'argument de la fonction (SpaceshipCreate).