Séance 3 : Communication avec API

🎯 Objectifs

  • Appeler une API externe.

  • Gérer erreurs, loaders et services dédiés.

📖 Partie théorique

Architecture client/serveur

  • Vue/Nuxt côté client, API côté serveur.

  • Communication via HTTP (REST, JSON, voire GraphQL).

Fetch API vs Axios

Fetch

  • fetch : natif, simple, mais moins de fonctionnalités.

Exemple :

fetch('http://localhost:3001/tasks')
  .then(response => response.json())
  .then(data => {
    console.log(data);
  });

Axios

  • axios : plus complet, gestion des interceptors, requêtes simplifiées.

Exemple :

import axios from 'axios';

axios.get('http://localhost:3001/tasks')
  .then(response => {
    console.log(response.data);
  });

Gestion des erreurs

  • Utilisation de try/catch pour capturer les erreurs réseau ou API.

Exemple avec Fetch :

async function fetchTasks() {
  try {
    const response = await fetch('http://localhost:3001/tasks');
    if (!response.ok) {
      throw new Error('Erreur lors de la récupération des tâches');
    }
    const data = await response.json();
    console.log(data);
  } catch (error) {
    // Affichage d’un message d’erreur à l’utilisateur
    alert('Une erreur est survenue : ' + error.message);
  }
}

Dans cet exemple, si la requête échoue (problème réseau, serveur indisponible, etc.), le bloc catch permet d’afficher un message d’erreur à l’utilisateur.

Exemple simple en Vue.js :

<template>
  <div>
    <button @click="fetchTasks">Charger les tâches</button>
    <div v-if="errorMessage" class="error">
      {{ errorMessage }}
    </div>
    <ul v-if="tasks.length">
      <li v-for="task in tasks" :key="task.id">{{ task.title }}</li>
    </ul>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const tasks = ref([])
const errorMessage = ref('')

async function fetchTasks() {
  errorMessage.value = ''
  try {
    const response = await fetch('http://localhost:3001/tasks')
    if (!response.ok) {
      throw new Error('Erreur lors de la récupération des tâches')
    }
    tasks.value = await response.json()
  } catch (error) {
    errorMessage.value = 'Une erreur est survenue : ' + error.message
  }
}
</script>

<style>
.error {
  color: red;
  margin: 1em 0;
}
</style>

Cet exemple affiche un message d’erreur à l’utilisateur si la récupération des tâches échoue.

Loaders

Pour afficher un loader pendant l'appel à l'API, il suffit d'ajouter une variable d'état isLoading et de l'utiliser dans le template :

<template>
  <div>
    <button @click="fetchTasks">Charger les tâches</button>
    <div v-if="isLoading" class="loader">Chargement...</div>
    <div v-if="errorMessage" class="error">
      {{ errorMessage }}
    </div>
    <ul v-if="tasks.length && !isLoading">
      <li v-for="task in tasks" :key="task.id">{{ task.title }}</li>
    </ul>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const tasks = ref([])
const errorMessage = ref('')
const isLoading = ref(false)

async function fetchTasks() {
  errorMessage.value = ''
  isLoading.value = true
  try {
    const response = await fetch('http://localhost:3001/tasks')
    if (!response.ok) {
      throw new Error('Erreur lors de la récupération des tâches')
    }
    tasks.value = await response.json()
  } catch (error) {
    errorMessage.value = 'Une erreur est survenue : ' + error.message
  } finally {
    isLoading.value = false
  }
}
</script>

<style>
.loader {
  color: #007bff;
  font-weight: bold;
  margin: 1em 0;
}
.error {
  color: red;
  margin: 1em 0;
}
</style>

Ici, le loader s'affiche tant que la requête est en cours (isLoading à true), puis disparaît dès que la réponse est reçue ou qu'une erreur survient.

Services dédiés

  • Création d'un service API pour centraliser les appels HTTP.

📝 Travaux pratiques

Étape 1 : Installation de JSON Server

JSON Server permet de créer une API REST complète à partir d'un simple fichier JSON.

Installation :

# Installation globale
npm install -g json-server

# Ou installation locale dans le projet
npm install --save-dev json-server

Étape 2 : Création du fichier de données

Créer db.json à la racine du projet :

{
  "tasks": [
    {
      "id": 1,
      "title": "Apprendre Vue 3",
      "description": "Maîtriser la Composition API et les nouveautés",
      "priority": "High",
      "completed": false,
      "createdAt": "2024-09-01T10:00:00Z",
      "dueDate": "2024-09-30T23:59:59Z"
    },
    {
      "id": 2,
      "title": "Créer un projet",
      "description": "Développer une application de gestion de tâches",
      "priority": "Medium",
      "completed": true,
      "createdAt": "2024-09-15T14:30:00Z",
      "dueDate": "2024-10-15T23:59:59Z"
    },
    {
      "id": 3,
      "title": "Déployer l'application",
      "description": "Mettre en ligne sur Netlify ou Vercel",
      "priority": "Low",
      "completed": false,
      "createdAt": "2024-09-20T09:15:00Z",
      "dueDate": "2024-11-01T23:59:59Z"
    }
  ],
  "users": [
    {
      "id": 1,
      "name": "Alice Dupont",
      "email": "[email protected]",
      "role": "admin"
    },
    {
      "id": 2,
      "name": "Bob Martin",
      "email": "[email protected]",
      "role": "user"
    }
  ]
}

Étape 3 : Configuration et démarrage de JSON Server

Ajouter les scripts dans package.json :

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "api": "json-server --watch db.json --port 3001"
  }
}

Pour exécuter simultanément Vue et l'API :

# Terminal 1 : Vue
npm run dev

# Terminal 2 : API JSON Server
npm run api

Étape 4 : URLs disponibles

Une fois JSON Server démarré sur le port 3001, les endpoints suivants sont disponibles :

Endpoints automatiques :

GET    /tasks           # Récupérer toutes les tâches
GET    /tasks/1         # Récupérer la tâche avec l'ID 1
POST   /tasks           # Créer une nouvelle tâche
PUT    /tasks/1         # Mettre à jour la tâche avec l'ID 1
PATCH  /tasks/1         # Mise à jour partielle de la tâche avec l'ID 1
DELETE /tasks/1         # Supprimer la tâche avec l'ID 1

GET    /users           # Récupérer tous les utilisateurs
GET    /users/1         # Récupérer l'utilisateur avec l'ID 1

Paramètres de requête supportés :

GET /tasks?completed=true           # Filtrer par statut
GET /tasks?priority=High            # Filtrer par priorité
GET /tasks?_sort=createdAt&_order=desc  # Trier par date (desc)
GET /tasks?_limit=10&_page=2        # Pagination
GET /tasks?q=Vue                    # Recherche textuelle

Étape 5 : Appels API dans Vue

  • Utilisez ces API pour lier vos tâches dans votre application Vue.

  • Gérez les états de chargement et d'erreur avec des loaders et des messages.

  • Créez des services dédiés pour organiser vos appels API.

Last updated