Partie 1 : QCM
1. Une station envoie POST /mesures avec un relevé valide. Le serveur l’enregistre immédiatement et renvoie la mesure créée avec son id. Quel statut est le plus approprié ?
- A)
200 OK - B)
201 Created - C)
202 Accepted - D)
204 No Content
2. Après un délai réseau dépassé, un client veut réessayer automatiquement une requête sans savoir si la première a abouti. Laquelle peut-il relancer sans risquer de doublon ni d’effet supplémentaire ?
- A)
POST /stations(créer une station) - B)
POST /stations/12/mesures(ajouter une mesure) - C)
PATCH /stations/12qui incrémente un compteur de relevés - D)
PUT /stations/12(remplacer entièrement la station 12)
3. Le tableau de bord demande GET /stations/9999, mais aucune station ne porte cet id. Que devrait renvoyer le serveur ?
- A)
200 OKavec un corps vide{} - B)
204 No Content - C)
404 Not Found - D)
400 Bad Request
4. Un développeur expose GET /stations/12/supprimer pour retirer une station. Quel est le problème principal ?
- A) le chemin mêle une ressource et une action, et
GETdoit rester sûr : il fautDELETE /stations/12 - B) il faudrait plutôt
POST /stations/12/supprimer, car une suppression modifie l’état - C) l’identifiant devrait passer en paramètre de requête :
GET /stations/supprimer?id=12 - D) il manque l’en-tête
Content-Type, requis pour une suppression
5. Laquelle de ces conceptions respecte le mieux l’interface uniforme de REST pour gérer des stations ?
- A)
POST /stations,GET /stations/12,POST /stations/12/update,POST /stations/12/delete - B)
POST /stations,GET /stations/12,PATCH /stations/12,DELETE /stations/12 - C)
POST /stations/create,GET /stations/12,PUT /stations/12,GET /stations/12/delete - D)
GET /stations?action=list,POST /stations?action=create,POST /stations?action=update
6. Au-dessus d’un protocole sans état, comment reconnaître un utilisateur connecté d’une requête à l’autre ?
- A) le client joint à chaque requête un cookie ou un jeton que le serveur vérifie
- B) le serveur retient l’adresse IP du client et la reconnaît aux requêtes suivantes
- C) on ouvre une connexion TCP permanente conservée pour toute la session
- D) le serveur garde en mémoire la liste des utilisateurs connectés, indexée par leur nom
7. Une API veut authentifier ses clients sans conserver d’état de session côté serveur. Elle émet un JWT (jeton signé) à la connexion. Comment valide-t-elle les requêtes suivantes ?
- A) elle compare le jeton à une liste de sessions actives conservée en mémoire
- B) elle redemande le mot de passe à chaque requête pour régénérer le jeton
- C) elle vérifie la signature du jeton avec sa clé ; si elle est valide, elle peut se fier aux informations du jeton
- D) elle interroge la base de données à chaque requête pour retrouver la session associée au jeton
8. Une préférence d’affichage propre à un utilisateur (thème clair ou sombre) doit être conservée entre ses visites. Où vaut-il mieux la placer ?
- A) dans un tableau en mémoire du serveur, partagé par toutes les requêtes
- B) dans la base de données principale, relue à chaque chargement de page
- C) dans un fichier de configuration du serveur, commun à tous les utilisateurs
- D) côté client (cookie ou stockage du navigateur), car la donnée est locale et non critique
9. Dans Express, la route app.get('/stations/:id', ...) reçoit la requête /stations/12?detail=complet. Comment lire respectivement 12 et complet ?
- A)
req.query.idetreq.params.detail - B)
req.params.idetreq.query.detail - C)
req.body.idetreq.body.detail - D)
req.params.idetreq.params.detail
10. Un gestionnaire POST lit req.body mais obtient undefined, alors que le client envoie pourtant du JSON avec l’en-tête Content-Type: application/json. Cause la plus probable ?
- A) le serveur n’a pas monté le middleware
express.json()(app.use(express.json())) - B) le corps est en réalité encodé en
multipart/form-data, qu’express.json()n’analyse pas - C)
req.bodyn’existe que pour les requêtesPUT, pas pourPOST - D) il faut lire
await req.body, car le corps arrive de façon asynchrone
Partie 2 : Questions à développement
Q1. Maîtrise et limites de HTTP
Un collègue affirme : « puisque HTTP est sans état, il est impossible d’y faire un panier d’achat. »
Expliquez la caractéristique en jeu, en distinguant la limite concrète qu’elle impose.
Dites pourquoi l’affirmation est fausse : par quel moyen peut-on contourner la limite ?
Q2. L’architecture REST
Deux API exposent les mêmes données : l’une fait POST /api?action=getUser&id=12, l’autre GET /users/12.
Présentez au moins trois contraintes REST et, pour chacune, une conséquence concrète sur la conception ou l’exploitation.
Servez-vous des deux exemples pour expliquer ce qui distingue une API « qui parle HTTP » d’une API réellement RESTful, et ce que la première perd.
Partie 3 : Analyse et réparation
Q1. Réparer une conception d’endpoints
Un stagiaire propose l’API suivante pour le réseau de boîtes à livres Lino. Plusieurs choix posent problème.
| Méthode | Chemin | But | Réponse en cas de succès |
|---|---|---|---|
GET |
/getBoites |
Lister les boîtes | 200 |
GET |
/boite?id=42 |
Détail d’une boîte | 200 |
POST |
/boites/42/modifier |
Modifier une boîte | 200 |
GET |
/boites/supprimer/42 |
Supprimer une boîte | 200 |
POST |
/boites |
Créer une boîte | 200 |
GET |
/boites/9999 (inexistante) |
Détail | 200 avec {} |
- Identifiez au moins cinq problèmes distincts (verbes, chemins, codes de statut, contraintes REST comme la sûreté des méthodes et l’interface uniforme).
- Proposez une version corrigée sous forme de tableau (méthode, chemin, code de succès, code d’erreur pertinent).
- Justifiez deux corrections en vous appuyant explicitement sur une contrainte REST ou sur la sémantique HTTP.
Q2. Analyser et réparer un protocole de collecte
Les stations de mesure d’un réseau IoT envoient leurs relevés au serveur.
Protocole actuel
- Pour enregistrer une mesure :
GET /enregistrer?station=12&pm25=34&temp=21 - Le serveur répond toujours
200 OK("ok"), même si des champs manquent ou sont invalides. - Pour lire la dernière mesure :
GET /mesure/12, qui renvoie200 OKavec{}si la station est inconnue. - Le tableau de bord, qui suit 500 stations, interroge
GET /mesurestoutes les 2 secondes pour tout rafraîchir.
Code du serveur (extrait)
router.get("/enregistrer", (req, res) => {
const m = Mesure.create(req.query);
res.send("ok");
});
router.get("/mesure/:id", async (req, res) => {
const m = await Mesure.findById(req.params.id);
res.json(m);
});
- Relevez les problèmes de choix de verbe, de codes de statut et de validation, pour l’enregistrement comme pour la lecture.
- Expliquez pourquoi rafraîchir par interrogation répétée (500 stations toutes les 2 secondes) est coûteux et peu adapté à un besoin de mise à jour en temps réel. Quel principe, du côté du serveur, permettrait de ne transmettre que les nouveautés sans que le client interroge en boucle ?
- Le code pour
/enregistrerignore que l’écriture dans une base de données est asynchrone. Corrigez-le, et indiquez brièvement comment éviter qu’une mesure invalide soit enregistrée. - Bonus: Donnez la version corrigée du code : bon verbe, bons statuts (
201,400,404, etc.), validation, et gestion de la station inconnue.
Partie 4 : Conception d’API
On attend une conception raisonnable, pas une spécification exhaustive.
Atmo, un réseau de stations de mesure de la qualité de l’air
Une ville déploie un réseau de stations fixes. Chaque station est un boîtier connecté portant plusieurs capteurs (particules fines PM2,5, température, humidité, niveau sonore) et produisant une mesure à intervalle régulier. On veut une API servant à la fois le public (citoyens, application web) et les services municipaux.
Questions auxquelles l’API doit répondre :
- Quelles stations existent, et où se trouvent-elles ?
- Quelle est la dernière mesure d’une station donnée ?
- Quelles stations sont dans un quartier donné, et laquelle a la pire qualité de l’air en ce moment ?
- Quel est l’historique des mesures d’une station sur une période ?
(a) Ressources et attributs: Identifiez les ressources principales et, pour chacune, ses attributs clés avec leur type (station, capteur, mesure, et leurs relations).
(b) Endpoints: Concevez les endpoints (méthode et chemin) qui répondent aux questions ci-dessus ; précisez en une ligne ce que chacun renvoie. Soignez les verbes, les chemins et l’usage des paramètres de route par rapport aux paramètres de requête (filtre par quartier, période d’historique, proximité).
(c) Stratégie de persistance: Proposez un modèle de données et indiquez où vivent les mesures. Justifiez votre choix selon les accès attendus : lire la dernière mesure d’une station, consulter un historique sur une période, et un volume de mesures qui croît sans fin. Nommez un compromis de votre choix.
(d) Bonus : Donnez une requête de votre API publique et la réponse JSON correspondante (par exemple la dernière mesure d’une station), cohérente avec le modèle de (c).