Aller au contenu

Exercice 04 - Pokemon API (Formatif)

Dans cet exercice vous devez créer un api avec Express.js qui couvre toutes les opérations CRUD sur une table MySQL. Vous trouverez la description des routes à créer plus bas.

Configuration du projet

  • Acceptez le devoir Gitub Classroom fourni par votre enseignant et clonez le projet.
  • Lancez la commande npm install pour installer automatiquement les modules express, dotenv et nodemon car ils sont déjà présent dans le fichier pacjage.json.
  • Les valeurs des paramètres de connexion à la base de données ainsi que le numéro de port doivent être enregistrées dans un fichier .env.
  • Pour le projet installez aussi les modules mysql ou mysql2 selon votre SGBD.
  • Vous devez utiliser une structure modèles, routes et contrôleur comme décrite dans la section Structure de projet avec Express.

Note

Une fois l'exercice terminé, faites un commit et un push de votre dernière version.

Importation de la base de données

Le script va créer la base de données bd_exercices ainsi que la table pokemon.

Routes à créer

Afficher un pokemon selon son id

route
GET /api/pokemons/:id
reponse
// Succès avec la route /api/pokemons/1
// Code de statut 200
{
    "nom":"Bulbasaur",
    "type_primaire":"Grass",
    "type_secondaire":"Poison",
    "pv":45,
    "attaque":49,
    "defense":49
}

// Erreur : Le pokemon n'est pas trouvé
// Code de statut 404
{
    "erreur":"Pokemon introuvable avec l'id 1245"
}

// Erreur : Il y a eu une erreur lors de la requête SQL 
// Code de statut 500
// Inscrivez à la console le code de statut SQL et le message d'erreur généré
{
    "erreur":"Echec lors de la récupération du pokemon avec l'id 1245"
}

Afficher une liste paginée de tous les pokemons

route
GET /api/pokemons/liste?page=1&type=grass

Créez une route qui va afficher la liste de tous les pokemons. Cette route sera paginée et n'affichera que 25 pokemons par page. Chaque pokemon a aussi un type primaire. On va pouvoir ajouter un filtre en paramêtre pour n'afficher que les pokemons qui sont du type choisi.

  • Le paramètre page est optionnel. S'il n'est pas fournie, on va retourner la page 1.
  • Le paramètre type est aussi optionnel. S'il n'est pas fournie, afficher tous les pokemons. Si le type ne correspond à aucun type primaire dans la table pokemon, on va retourner un tableau vide avec les valeurs nombrePokemonTotal à 0 et la page et totalPage à 1.

Astuce

Dans ma solution j'ai seulement ajouté le type primaire comme paramètre de la requête SQL. Ensuite j'ai utilisé array.slice() pour effectuer la pagination sur le tableau de résultats.

reponse
// Succès avec la route /api/pokemons/liste?page=2&type=grass
// Code de statut 200
{
    "pokemons" : [
        {
            "nom":"Bulbasaur",
            "type_primaire":"Grass",
            "type_secondaire":"Poison",
            "pv":45,
            "attaque":49,
            "defense":49
        },
        {
          ...
        }
    ],
    // La valeur passé du paramêtre, si aucune laissez vide ("type" : "")
    "type" : "Grass",
    // Le nombre total de pokemons selon le filtre appliqué (ici il y a 94 pokemons de type "Grass").
    "nombrePokemonTotal" : 94,
    // La valeur du paramètre, sinon inscrire 1.
    "page" : 2,
    // Le nombre de pages au total, le nombre de pokemons totaux divisés par le 
    // nombre de pokemons par page (25) arrondis à l'entier supérieur.
    "totalPage" : 4
}

// Erreur : Il y a eu une erreur lors de la requête SQL 
// Code de statut 500
// Inscrivez à la console le code de statut SQL et le message d'erreur généré
{
    "erreur":"Echec lors de la récupération de la liste des pokemons"
}

Ajouter un pokemon

route
POST /api/pokemons

// Structure des données du corps de la requête, en json. À remplacer par des données valides
{
    "nom":"",
    "type_primaire":"",
    "type_secondaire":"",
    "pv":0,
    "attaque":0,
    "defense":0
}
reponse
// Succès
// Code de statut 201
{
    "message" : "Le pokemon [nom] a été ajouté avec succès",
    // Nouvelle valeur du pokemon
    "pokemon" : {
        "id": 999, // Le id du nouveau pokemon dans la base de données
        "nom":"",
        "type_primaire":"",
        "type_secondaire":"",
        "pv":0,
        "attaque":0,
        "defense":0
    }
}

// Erreur : Le format du JSON dans le corps de la requête est invalide
// Exemple ici il manquait les champs pv et attaque.
// Code de statut 400
{
    "erreur":"Le format des données est invalide",
    "champ_manquant": [
        "pv",
        "attaque"
    ]
}

// Erreur : Il y a eu une erreur lors de la requête SQL 
// Code de statut 500
// Inscrivez à la console le code de statut SQL et le message d'erreur généré
{
    "erreur":"Echec lors de la création du pokemon [nom_du_pokemon]"
}

Modifier un pokemon

route
PUT /api/pokemons/:id

// Structure des données du corps de la requête, en json. À remplacer par des données valides
{
    "nom":"",
    "type_primaire":"",
    "type_secondaire":"",
    "pv":0,
    "attaque":0,
    "defense":0
}
reponse
// Succès
// Code de statut 200
{
    "message" : "Le pokemon id [id] a été modifié avec succès",
    // Nouvelle valeur du pokemon
    "pokemon" : {
        "id": 999,
        "nom":"",
        "type_primaire":"",
        "type_secondaire":"",
        "pv":0,
        "attaque":0,
        "defense":0
    }
}

// Erreur : Le id n'existe pas dans la base de données
// Code de statut 404
{
    "erreur":"Le pokemon id [id] n'existe pas dans la base de données",
}

// Erreur : Le format du JSON dans le corps de la requête est invalide
// Code de statut 400
// Exemple ici il manquait les champs pv et attaque.
{
    "erreur":"Le format des données est invalide",
    "champ_manquant": [
        "pv",
        "attaque"
    ]
}

// Erreur : Il y a eu une erreur lors de la requête SQL 
// Code de statut 500
// Inscrivez à la console le code de statut SQL et le message d'erreur généré
{
    "erreur":"Echec lors de la modification du pokemon [nom_du_pokemon]"
}

Supprimer un pokemon

route
DELETE /api/pokemons/:id
reponse
// Succès
// Code de statut 200
{
    "message" : "Le pokemon id [id] a été supprimé avec succès",
    // Valeur du pokemon supprimé
    "pokemon" : {
        "id": 999,
        "nom":"",
        "type_primaire":"",
        "type_secondaire":"",
        "pv":0,
        "attaque":0,
        "defense":0
    }
}

// Erreur : Le id n'existe pas dans la base de données
// Code de statut 404
{
    "erreur":"Le pokemon id [id] n'existe pas dans la base de données",
}

// Erreur : Il y a eu une erreur lors de la requête SQL 
// Code de statut 500
// Inscrivez à la console le code de statut SQL et le message d'erreur généré
{
    "erreur":"Echec lors de la suppression du pokemon [nom_du_pokemon]"
}

Documentation

Vous devez créer la documentation adéquate pour l'api que vous avez développé à l'exercice 04.

La méthode pour documenter l'api doit être celle décrite dans les notes de cours à la section Documentation d'un API avec OpenAPI

Détail de la documentation

  • Ajoutez la route /api/docs qui affichera la page de la documentation
  • Configurez les valeurs de la section serveurs pour vous permettre de tester l'api depuis la documentation
  • Les 5 routes doivent être documentées
  • Les paramètres doivent bien être détaillés.
  • Toute les réponses doivent être décrite avec un exemple de valeur.
  • Utiliser un schema pour le modèle pokemon et utilisez le lorsque c'est possible dans votre documentation