Tester des API sans Postman : ce dont tu as vraiment besoin
Postman est passé de client REST léger à plateforme complète — workspaces, comptes, sync, collections dans le cloud. Si ton métier est de gérer des centaines de requêtes en équipe, très bien. Mais pour le quotidien du « est-ce que cet endpoint marche et pourquoi il renvoie 401 ? », il te faut exactement deux capacités : envoyer des requêtes HTTP arbitraires et inspecter ce qui revient (plus, pour les webhooks, un moyen de voir ce qu'on *t'*envoie). Les deux tiennent dans un onglet de navigateur.
Anatomie d'une requête REST
Toute requête HTTP a quatre parties, et la plupart des bugs vivent dans exactement l'une d'elles :
| Partie | C'est quoi | Erreur classique |
|---|---|---|
| Méthode | GET, POST, PUT, PATCH, DELETE | POST sur une route GET-only → 405 |
| URL | Endpoint + query string | & ou espace non encodé dans un paramètre |
| Headers | Métadonnées : auth, content type, accept | Content-Type: application/json manquant |
| Body | La charge utile (POST/PUT/PATCH) | Envoyer du form-encoded là où l'API attend du JSON |
L'équivalent en curl, la langue commune de toute doc d'API :
curl -X POST "https://api.example.com/v1/orders" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOi..." \
-d '{"product_id": 42, "quantity": 2}'
Un API Tester te donne la même puissance avec une interface : choisis la méthode, ajoute les headers, colle le body, envoie. Plus rapide à itérer qu'un one-liner curl à réécrire, rien à installer, et rien à synchroniser dans le cloud de qui que ce soit.
Les trois patterns d'auth que tu vas croiser
Bearer token (OAuth2, JWT, la plupart des API modernes) :
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Clé d'API — en header ou en paramètre de query, selon la doc :
X-API-Key: sk_live_abc123
Basic auth — username:password encodé en Base64 (encodé, pas chiffré — HTTPS obligatoire) :
Authorization: Basic dXNlcjpwYXNzd29yZA==
Lire la réponse comme un pro
Lis dans cet ordre — statut, headers, body :
- 2xx — succès.
201= créé,204= succès sans body (ne le parse pas). - 401 vs 403 — la distinction qui économise des heures :
401= « je ne sais pas qui tu es » (credentials absents/expirés/malformés),403= « je sais qui tu es, et tu n'as pas le droit » (permissions/scopes). - 422 — le serveur a compris ton JSON mais rejette les valeurs. Le body dit en général quel champ.
- 429 — rate limit atteint ; cherche un header
Retry-After. - 5xx — leur problème, pas le tien (en général).
Les headers racontent la méta-histoire : Content-Type te dit comment parser le body, X-RateLimit-Remaining te dit à quelle distance tu es de la falaise. Et quand le body est un mur de JSON minifié, colle-le dans un JSON Formatter pour rendre la structure lisible avant d'accuser le mauvais champ.
Webhooks : tester le trafic qui circule dans l'autre sens
Un appel d'API, c'est toi qui poses une question à un serveur. Un webhook, c'est l'inverse : le serveur *t'*appelle quand quelque chose se produit — Stripe au paiement réussi, GitHub au push, ta CI en fin de build. Concrètement, c'est juste un POST HTTP vers une URL que tu as enregistrée.
C'est cette inversion qui rend les webhooks pénibles à tester : l'émetteur a besoin d'une URL joignable publiquement, et localhost:3000 n'en est pas une. Et tu ne peux pas poser de breakpoint dans le code de Stripe pour voir ce qu'ils ont envoyé.
Le workflow de l'URL de capture
La solution standard est une URL de capture : un endpoint public jetable qui accepte tout et te montre la requête complète. Avec un Webhook Tester, la boucle ressemble à ça :
- Génère une URL unique — du genre
https://.../hook/a1b2c3. - Enregistre-la comme endpoint de webhook dans le service émetteur (dashboard Stripe, settings du repo GitHub, etc.).
- Déclenche l'événement — fais un paiement de test, pousse un commit.
- Inspecte la capture : méthode, chaque header, et le body brut. C'est la vérité terrain de ce que l'émetteur envoie réellement — qui contredit régulièrement sa propre doc.
- Écris ton handler contre la réalité, puis rejoue le payload capturé contre ton vrai endpoint :
curl -X POST "http://localhost:3000/webhooks/stripe" \
-H "Content-Type: application/json" \
-H "Stripe-Signature: t=1720598400,v1=5257a869e7..." \
-d @payload-capture.json
Rejouer bat re-déclencher : tu itères sur ton handler en quelques secondes au lieu de refaire un paiement de test à chaque modification de code.
Vérifie les signatures, sinon n'importe qui peut appeler ton endpoint
Un endpoint de webhook est une URL publique qui modifie ton système — si tu ne vérifies pas l'authenticité, quiconque découvre l'URL peut forger des événements (« paiement réussi ! »). Le mécanisme standard est la signature HMAC : l'émetteur hache le body brut avec un secret partagé et met le résultat dans un header ; toi, tu recalcules et tu compares.
const crypto = require("crypto");
const attendu = crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(rawBody) // le body BRUT — avant tout parsing JSON
.digest("hex");
const valide = crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(attendu)
);
Deux modes d'échec expliquent presque tous les bugs « signature mismatch » : calculer le HMAC sur le body parsé puis re-sérialisé au lieu des octets bruts (l'ordre des clés et les espaces changent le hash), et un middleware du framework qui consomme le body brut avant ton handler. Respecte aussi le timestamp que la plupart des providers embarquent dans le header de signature — rejette les événements de plus de ~5 minutes pour bloquer les attaques par rejeu.
Déboguer l'auth avec les JWT
Quand une requête échoue en 401 alors que le token a l'air correct, arrête de deviner et décode-le. Un JWT, c'est trois segments Base64url — header, payload, signature — et les deux premiers sont lisibles par n'importe qui. Colle le token dans un JWT Decoder et vérifie, dans l'ordre :
exp— token expiré, la cause n°1. C'est un timestamp Unix ; compare avec maintenant.iss/aud— token émis par/pour un autre environnement (token de staging contre l'API de prod, grand classique).scope/roles— présents mais insuffisants → voilà ton 403 expliqué.algdans le header — un algorithme inattendu, et la vérification de signature échouera côté serveur.
Tu construis le côté serveur de l'auth ? Génère des tokens de test avec les claims de ton choix — un valide, un expiré, un sans le bon scope — avec un JWT Builder, et tu peux exercer chaque branche de ton middleware sans brancher un vrai fournisseur d'identité.
Un workflow qui couvre 95 % des cas
- Reproduis l'appel dans un testeur d'API — isole-le du code de ton appli.
- Lis statut → headers → body, dans cet ordre.
- 401 ? Décode le token. 422 ? Formate et relis le body que tu as envoyé.
- Webhook capricieux ? Capture le vrai payload, vérifie le calcul de signature, rejoue en local.
- Seulement ensuite, ouvre le code de ton application — maintenant tu sais quel côté ment.
Envoie ta première requête maintenant
Lance une vraie requête depuis ton navigateur avec l'API Tester — méthodes, headers, auth et réponses formatées inclus. Aucun compte requis.