API — Conventions générales¶
Cette page décrit les règles transverses qui s'appliquent à tous les endpoints REST de PerfShop. Elle est la première à lire avant d'aborder les références par contrôleur.
Périmètre
Le backend PerfShop expose environ 95 endpoints répartis sur 19 contrôleurs Spring. Toutes les conventions listées ici sont appliquées uniformément, sauf mention explicite dans la page du contrôleur concerné.
Base URL et versioning¶
| Environnement | Base URL |
|---|---|
| Développement local (Docker Compose) | http://localhost:9080 |
| Production (nginx sur NAS) | https://perfshop-api.perfshop.io |
PerfShop n'utilise pas de versioning explicite dans le chemin : il n'y a pas de préfixe /v1/. Toute l'API vit sous /api/.... Les évolutions suivent le modèle « rolling release » — les changements breaking sont documentés dans le journal de version.
Format des échanges¶
- Requêtes : JSON (
Content-Type: application/json), saufPOST /api/admin/products/{id}/imagequi attendmultipart/form-data. - Réponses : JSON systématiquement (même pour les erreurs). Les corps sont encodés en UTF-8.
- Dates : format ISO 8601 (
2026-04-08T10:30:00Zpour les timestamps,1990-05-15pour les dates nues). - Montants monétaires :
BigDecimalsérialisé comme nombre JSON avec 2 décimales (ex.49.99). - Identifiants :
Long(entier 64 bits) pour les entités DB, UUID (string) pour les tokens.
Les trois mécanismes d'authentification¶
PerfShop cohabite trois systèmes d'authentification distincts, chacun dédié à une population d'utilisateurs.
flowchart LR
subgraph CLIENT["Client HTTP"]
U1[Utilisateur final<br/>navigateur]
U2[Formateur<br/>chaos-admin]
U3[Étudiant<br/>page chaos]
end
subgraph API["Backend Spring Boot"]
A1[Session HTTP<br/>JSESSIONID cookie]
A2[X-Admin-Token<br/>UUID en mémoire]
A3[X-Student-Token<br/>UUID par étudiant]
end
U1 -->|"POST /api/auth/login"| A1
U2 -->|"POST /api/admin/login"| A1
U2 -.->|"ou header direct"| A2
U3 -->|"POST /pedagogique/join"| A3
A1 --> B1[CartController<br/>OrderController<br/>UserController]
A2 --> B2[AdminController<br/>ChaosController<br/>BusinessChaosController<br/>SecurityChaosController<br/>FunctionalChaosController<br/>ChaosScriptingController]
A3 --> B3[ChaosStudentController<br/>endpoints pédagogiques]
Session HTTP (utilisateur final)¶
- Établie par
POST /api/auth/loginavec email + password. - Stockée côté serveur dans la
HttpSessionSpring (clé :LOGGED_IN_USER). - Transmise automatiquement par le navigateur via le cookie
JSESSIONID. - Durée : 30 minutes d'inactivité par défaut (
server.servlet.session.timeout). - Détruite par
POST /api/auth/logout(sauf en Chaos Métier niveau 3+ — voir A11 grace period).
X-Admin-Token (formateur)¶
- Généré par
POST /api/admin/loginen plus du cookie de session. Retourné dans le body sous la cléadminToken. - UUID aléatoire stocké en mémoire dans une
ConcurrentHashMapcôté serveur (cléVALID_ADMIN_TOKENSdansAdminController). - Non persistant : réinitialisé au redémarrage du backend (comportement intentionnel — valeur pédagogique pour les démos chaos mémoire).
- Conçu pour l'usage cross-origin (scripts
curl, tests automatisés, appels depuischaos-adminqui est servi par nginx sur un autre port). - Transmis dans le header HTTP :
X-Admin-Token: 550e8400-e29b-41d4-a716-446655440000.
Double authentification
Les contrôleurs d'administration acceptent indifféremment le cookie de session OU le header X-Admin-Token. L'utilitaire AdminAuth.isAdmin(session, token) centralise cette vérification.
X-Student-Token (étudiant)¶
- Généré par
POST /api/chaos/student/pedagogique/joinquand un étudiant rejoint un parcours. - UUID unique par étudiant, stocké côté serveur dans
PedagogiqueSessionService(base de données + cache mémoire optionnel). - Utilisé par les endpoints pédagogiques (
/validate,/logique/questions,/finale/validate, etc.) pour isoler la progression de chaque étudiant. - Transmis dans le header HTTP :
X-Student-Token: ab12cd34-.... - Permet aussi à la commande (
POST /api/orders) de recevoir leagentCodepédagogique si l'étudiant est en parcours actif.
Format standard des erreurs¶
Toute réponse en erreur (4xx ou 5xx) retourne un objet JSON contenant au minimum la clé error :
Certaines erreurs ajoutent des clés contextuelles :
{
"error": "LICENSE_REQUIRED",
"chaos": "performance",
"requested": 3,
"maxFree": 1,
"message": "Niveau 3 non disponible sans licence. Maximum : 1",
"portalUrl": "https://perfshop.io"
}
{
"error": "Données invalides",
"fields": {
"phone": "Format téléphone invalide pour FR — attendu : 10 chiffres commençant par 0 (ex: 0612345678)",
"postalCode": "Code postal FR invalide '7500' — attendu : 5 chiffres (ex: 75001)"
}
}
Les messages sont toujours résolus côté serveur via I18nService à partir de clés messages_XX.properties — jamais renvoyés sous forme de clé brute.
Codes HTTP utilisés¶
PerfShop suit strictement la sémantique HTTP standard, avec une particularité importante pour le code 402.
| Code | Usage dans PerfShop |
|---|---|
| 200 OK | Succès standard d'une requête GET ou d'une action idempotente |
| 201 Created | Création d'une ressource (POST /api/orders, POST /api/admin/products, POST /api/admin/users) |
| 400 Bad Request | Paramètre manquant ou invalide, format JSON incorrect |
| 401 Unauthorized | Authentification manquante ou invalide (session absente, token inconnu) |
| 402 Payment Required | Fonctionnalité réservée aux licences payantes (freemium). Voir freemium vs Pro |
| 403 Forbidden | Authentifié mais non autorisé (mode étudiant bloqué, compte non superadmin, ressource d'un autre utilisateur) |
| 404 Not Found | Ressource introuvable — aussi retournée par le portail admin caché quand S10–S12 sont inactifs (dissimulation) |
| 409 Conflict | Conflit d'état : étape pédagogique incorrecte, licence déjà active, aucun parcours actif |
| 422 Unprocessable Entity | Validation métier échouée (format email, Luhn carte, date naissance, etc.) |
| 429 Too Many Requests | Limite atteinte : /pedagogique/join refuse au-delà de 500 sessions simultanées |
| 500 Internal Server Error | Exception non gérée, deadlock DB, erreur chaos fonctionnel (NPE, StackOverflow, OOM) |
Le cas particulier du 402 Payment Required¶
PerfShop utilise le code 402 Payment Required de façon systématique pour signaler qu'une fonctionnalité dépasse les limites de la licence courante. C'est un choix d'API délibéré : il rend la règle freemium auto-descriptive — un client HTTP peut détecter sans ambiguïté qu'il touche un mur de licence, séparément d'un simple 403 Forbidden.
Les endpoints qui retournent 402 portent tous la même structure de corps LICENSE_REQUIRED documentée plus haut.
Internationalisation des messages d'erreur¶
PerfShop est multilingue, mais ne négocie pas la langue via Accept-Language HTTP. La langue est fixée globalement par une variable d'environnement lue au démarrage du backend :
PERFSHOP_LANG=fr # défaut
PERFSHOP_LANG=en
PERFSHOP_LANG=es # (à venir)
PERFSHOP_LANG=de # (à venir)
PERFSHOP_LANG=it # (à venir)
Conséquences pratiques :
- Un même déploiement parle une seule langue.
- Pour changer de langue, il faut redémarrer le backend avec une autre valeur de
PERFSHOP_LANG. - Les messages sont résolus depuis
messages_fr.propertiesoumessages_en.properties(ou futurs fichiers). - Les en-têtes
Accept-Languageenvoyés par le client sont ignorés.
Ce choix est dicté par l'usage pédagogique : une salle de formation travaille dans une langue donnée, et la cohérence des logs et des messages d'erreur entre tous les postes est plus importante que la localisation par utilisateur.
Voir Internationalisation pour le détail du mécanisme.
Headers CORS¶
Le backend accepte les appels cross-origin des frontends internes via CorsConfig.java. Les origines autorisées en développement incluent typiquement :
http://localhost:3010(frontend e-commerce React)http://localhost:3011(page d'accueil welcome)http://localhost:3012(chaos-admin)http://localhost:3013(monitoring)http://localhost:3014(scripts-ui, jmeter-ui)
Les headers X-Admin-Token et X-Student-Token sont explicitement exposés dans la configuration CORS pour permettre leur lecture/écriture depuis les navigateurs.
En production, les origines sont restreintes aux domaines *.perfshop.io.
Pagination¶
Les endpoints retournant des listes paginées utilisent Spring Data Pageable. Format standard :
Requête :
Réponse :
{
"content": [ /* ... éléments de la page ... */ ],
"totalElements": 147,
"totalPages": 8,
"number": 0,
"size": 20,
"first": true,
"last": false
}
| Paramètre | Défaut | Description |
|---|---|---|
page |
0 |
Numéro de page (0-indexé) |
size |
20 |
Nombre d'éléments par page |
sort |
varie | Colonne de tri (whitelist côté serveur pour éviter les PropertyReferenceException) |
Whitelist de tri
Pour GET /api/products, seules les colonnes id, name, price, category, createdAt, stock sont acceptées. Un paramètre sort inconnu est silencieusement remplacé par id.
Headers de réponse spécifiques¶
| Header | Émis par | Description |
|---|---|---|
X-Debug-Token |
POST /api/auth/login |
Uniquement en Chaos Sécurité niveau ≥ 3 (faille S7). Token HMAC faiblement signé. |
X-Session-Token |
Endpoints checkout | Chaos Scripting niveau ≥ 1 — voir Chaos Scripting |
X-Request-ID |
Endpoints checkout | Chaos Scripting niveau ≥ 1 |
X-Action-Token |
Endpoints checkout | Chaos Scripting niveau ≥ 2 |
X-CSRF-Token |
Endpoints checkout | Chaos Scripting niveau ≥ 3 |
X-Step-Token |
Endpoints checkout | Chaos Scripting niveau ≥ 3 |
X-Signature |
Endpoints checkout | Chaos Scripting niveau ≥ 3 (HMAC) |
Ces headers sont documentés en détail dans la page Chaos Scripting.
Conventions de nommage des endpoints¶
PerfShop suit une arborescence par fonction métier puis par rôle :
/api/auth/* → authentification utilisateur final
/api/products/* → catalogue produit (public)
/api/cart/* → panier (public ou connecté)
/api/checkout/* → parcours checkout 4 étapes
/api/orders/* → commandes (connecté)
/api/countries → listes de référence
/api/admin/* → administration (formateur)
/api/admin/chaos/* → pilotage chaos (formateur)
/api/admin/portal/* → portail caché (chaos sécurité niveau Master)
/api/chaos/public/* → lectures chaos (monitoring, sans auth)
/api/chaos/frontend/* → relais état chaos frontend
/api/chaos/student/* → page étudiant (parcours pédagogiques)
/api/license/* → gestion de la licence
Les endpoints /api/chaos/public/* et /api/chaos/frontend/state (en GET) sont exclus du ChaosInterceptor, ce qui garantit qu'ils répondent toujours — même quand le reste du backend est saturé par un chaos actif. C'est la propriété qui permet au monitoring étudiant de continuer à afficher un état cohérent en conditions de panne simulée.
Exemple minimal avec curl¶
Scénario : login utilisateur, récupération du profil, ajout d'un produit au panier.
# 1. Login — récupère le cookie de session dans /tmp/cookies.txt
curl -c /tmp/cookies.txt \
-H "Content-Type: application/json" \
-d '{"email":"alice@example.com","password":"alice123"}' \
http://localhost:9080/api/auth/login
# 2. Profil (réutilise le cookie)
curl -b /tmp/cookies.txt http://localhost:9080/api/auth/me
# 3. Ajout panier
curl -b /tmp/cookies.txt \
-H "Content-Type: application/json" \
-d '{"productId":1,"quantity":2}' \
http://localhost:9080/api/cart/add
Scénario admin avec X-Admin-Token (sans cookie) :
# 1. Login admin — récupère adminToken dans le JSON de réponse
TOKEN=$(curl -s \
-H "Content-Type: application/json" \
-d '{"email":"admin@perfshop.fr","password":"admin"}' \
http://localhost:9080/api/admin/login | jq -r '.adminToken')
# 2. Pilotage chaos CPU niveau 3
curl -H "X-Admin-Token: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"intensity":80,"ratio":2}' \
http://localhost:9080/api/admin/chaos/cpu
# 3. Statut consolidé
curl -H "X-Admin-Token: $TOKEN" \
http://localhost:9080/api/admin/chaos/status
Points d'attention transverses¶
Endpoints intentionnellement vulnérables
Certains endpoints deviennent délibérément vulnérables lorsque le Chaos Sécurité dépasse un certain niveau. Ces comportements sont pédagogiques : ils servent à illustrer les failles OWASP dans un environnement contrôlé. La page Chaos Sécurité liste ces failles exhaustivement, et chaque page d'endpoint signale quand elle est concernée.
Le portail admin caché
Le contrôleur AdminPortalController (/api/admin/portal/*) retourne systématiquement 404 quand le Chaos Sécurité est strictement inférieur au niveau 4 (Master). Ce comportement est intentionnel — il permet à l'étudiant de découvrir le portail par fuzzing uniquement quand le formateur a activé le niveau Master. Voir admin-portal.md.
Le 402 freemium ne bloque jamais le backend
Un endpoint qui retourne 402 n'interrompt pas les chaos déjà en cours : il empêche uniquement un étudiant sans licence d'en activer de nouveaux au-delà du niveau gratuit autorisé. Le formateur avec licence peut continuer à piloter le chaos normalement.