Envoyer des requêtes avec curl et Postman

Les deux outils que vous utiliserez tous les jours, et quand choisir l’un ou l’autre.

Jusqu’ici, vous avez envoyé des requêtes depuis un navigateur et depuis les boutons Envoyer de ces pages. Cela marche pour des GET simples, et pour rien d’autre. Pour choisir la méthode, fixer des en-têtes ou envoyer un corps, il vous faut un vrai client. Presque tous ceux qui testent des API finissent par en utiliser deux : curl en ligne de commande, et un client graphique comme Postman. Cette leçon couvre assez de chacun pour suivre le reste du tutoriel.

curl

curl est un programme en ligne de commande qui envoie une requête et affiche la réponse. Il est installé par défaut sur macOS, sur la plupart des systèmes Linux et sur Windows 10 et 11. Vérifiez avec curl --version. C’est aussi le format que les développeurs utilisent pour partager des requêtes : la documentation des API, les outils de développement du navigateur et Postman savent tous afficher ou exporter une requête sous forme de commande curl, donc vous devrez savoir les lire même si vous préférez un autre outil.

Sans option, curl n’affiche que le corps. Ajoutez -i pour inclure la ligne de statut et les en-têtes de réponse, ce que vous voulez presque toujours quand vous testez :

Terminal
curl -i https://api.testingapis.com/api/health
Sortie
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
date: Sun, 11 Oct 2026 11:47:45 GMT
server: Kestrel
x-powered-by: TestingAPIs
transfer-encoding: chunked

{"status":"healthy","uptimeSeconds":76890,"timestamp":"2026-10-11T11:47:46Z"}

Pour plus de détails, -v (verbeux) affiche aussi la requête envoyée par curl, marquée par >, et les en-têtes de réponse, marqués par <. Les lignes qui commencent par * décrivent la connexion. Utilisez-le quand une requête ne se comporte pas comme prévu et que vous voulez voir exactement ce qui est passé sur le réseau.

Terminal
curl -v https://api.testingapis.com/api/health
Sortie (réduite)
* Host api.testingapis.com:443 was resolved.
* IPv4: 135.13.233.203
* Established connection to api.testingapis.com (135.13.233.203 port 443)
* using HTTP/1.x
> GET /api/health HTTP/1.1
> Host: api.testingapis.com
> User-Agent: curl/8.18.0
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< content-type: application/json; charset=utf-8
< date: Sun, 11 Oct 2026 11:49:47 GMT
< transfer-encoding: chunked
...

curl a ajouté trois en-têtes que vous n’aviez pas demandés : Host, User-Agent et Accept. Chaque client ajoute des valeurs par défaut, et chacun ajoute les siennes. Quand la même requête marche dans Postman et échoue dans curl, un en-tête par défaut en est souvent la cause.

Méthode, en-têtes et corps

Trois options couvrent la plupart des requêtes. -X fixe la méthode. -H ajoute un en-tête et peut être répété. -d envoie un corps. Ceci envoie un POST avec un corps JSON à un point d’accès qui renvoie ce qu’il a reçu :

Terminal
curl -X POST https://api.testingapis.com/api/methods/post \
  -H "Content-Type: application/json" \
  -d '{"name":"Asha","role":"tester"}'
Sortie
{"method":"POST","message":"POST request received","path":"/api/methods/post","query":{},"contentType":"application/json","bodyLength":31,"bodyTruncated":false,"body":"{\"name\":\"Asha\",\"role\":\"tester\"}","timestamp":"2026-09-30T18:31:16Z"}

La barre oblique inverse en fin de ligne permet à la commande de continuer sur la ligne suivante dans bash et zsh. Le corps est entre guillemets simples pour que le shell ne touche pas aux guillemets doubles à l’intérieur. Si vous oubliez l’en-tête Content-Type, curl envoie application/x-www-form-urlencoded, parce que -d a été conçu pour les formulaires HTML, et beaucoup d’API refuseront le corps.

curl 7.82 et suivants ont un raccourci, --json, qui envoie le corps, fixe Content-Type: application/json et Accept: application/json, et passe la méthode en POST. Celui-ci crée une vraie tâche :

Terminal
curl --json '{"title":"Learn curl","completed":false,"userId":1}' \
  https://api.testingapis.com/api/Todos
Sortie
{"message":"Todo created successfully","data":{"id":31,"userId":1,"title":"Learn curl","completed":false,"priority":"medium","dueDate":""}}

L’ID que vous recevrez sera différent, parce que d’autres personnes créent aussi des tâches. Pour PUT ou PATCH, ajoutez -X PUT ou -X PATCH à côté de --json.

Temps et scripts

-w affiche, après la réponse, des valeurs mesurées par curl. Combiné avec -s (silencieux, sans barre de progression) et -o /dev/null (jeter le corps), il vous donne un résumé en une ligne :

Terminal
curl -s -o /dev/null \
  -w "status %{http_code}  total %{time_total}s  size %{size_download} bytes\n" \
  https://api.testingapis.com/api/Products
Sortie
status 200  total 0.382512s  size 5846 bytes

Sous Windows, utilisez -o NUL au lieu de -o /dev/null. time_total inclut la résolution DNS, la connexion et TLS, donc la première requête est souvent plus lente que les suivantes. La leçon sur la performance décompose ce chiffre plus finement.

curl sous Windows

Windows mérite sa propre section, car la même commande peut se comporter de trois façons selon le shell.

Dans Windows PowerShell 5.1 (la version livrée avec Windows), curl n’est pas curl. C’est un alias de Invoke-WebRequest, une commande PowerShell avec d’autres options, donc curl -i échoue avec une erreur déroutante. Tapez curl.exe pour lancer le vrai programme. PowerShell 7 a supprimé l’alias, mais taper curl.exe marche dans les deux : c’est une bonne habitude.

Les guillemets sont le second problème. Windows PowerShell 5.1 retire les guillemets doubles à l’intérieur des arguments quand il les transmet à des programmes comme curl.exe. La commande ci-dessous a l’air juste, et le serveur reçoit un JSON cassé :

PowerShell 5.1
PS> curl.exe -s -X POST https://api.testingapis.com/api/methods/post -H "Content-Type: application/json" -d '{"name":"Asha"}'
{"method":"POST", ... "bodyLength":11, ... "body":"{name:Asha}", ...}

Le corps est arrivé sous la forme {name:Asha}, qui n’est pas du JSON. PowerShell 7.3 et suivants transmettent correctement les guillemets. Sur les versions plus anciennes, la solution la moins pénible est de mettre le corps dans un fichier et de faire pointer curl dessus avec @. Les guillemets autour de "@body.json" empêchent PowerShell de traiter le @ comme sa propre syntaxe.

PowerShell
# body.json contains {"name":"Asha","role":"tester"}
curl.exe -s --json "@body.json" https://api.testingapis.com/api/methods/post

Dans l’ancienne Invite de commandes (cmd.exe), les guillemets simples ne veulent rien dire : entourez le corps de guillemets doubles et échappez ceux de l’intérieur avec une barre oblique inverse. Le caractère de continuation de ligne est ^ au lieu de la barre oblique inverse :

Invite de commandes
curl -X POST https://api.testingapis.com/api/methods/post ^
  -H "Content-Type: application/json" ^
  -d "{\"name\":\"Asha\",\"role\":\"tester\"}"

Postman et les autres clients graphiques

Un client graphique fait le même travail que curl avec un formulaire au lieu d’une commande : vous choisissez la méthode dans une liste, tapez l’URL, remplissez en-têtes et corps dans des onglets, et cliquez sur Send. La réponse s’affiche dessous, mise en forme, avec le statut, le temps et la taille. Postman est le plus utilisé. Insomnia et Bruno fonctionnent de la même façon, et Bruno stocke tout sous forme de simples fichiers, ce que certaines équipes préfèrent parce que les requêtes peuvent vivre dans le même dépôt Git que le code. Les idées ci-dessous valent pour tous, avec les noms de Postman.

Les collections

Une collection est un groupe enregistré de requêtes, en général une par API, avec des dossiers à l’intérieur. C’est la raison de choisir un client graphique plutôt que curl pour un projet sur lequel vous travaillez des mois. Vous construisez les requêtes une fois et partagez la collection avec l’équipe.

Inutile de la construire à la main. Cette API publie un document OpenAPI, une description lisible par machine de chaque point d’accès, à l’adresse https://api.testingapis.com/openapi/v1.jsonconnectez-vous pour voir. Dans Postman, choisissez Import, collez cette URL, et il crée une collection avec une requête par point d’accès. La plupart des API que vous testerez au travail auront un fichier similaire, et c’est le moyen le plus rapide de démarrer sur une API inconnue.

Environnements et variables

Les vrais projets font tourner la même API à plusieurs endroits : le portable d’un développeur, un serveur de test, la préproduction, la production. Les requêtes sont les mêmes, à l’URL de base et aux identifiants près. Postman gère cela avec les environnements. Créez-en un nommé "testingapis" avec une variable baseUrl valant https://api.testingapis.com, puis écrivez vos URL de requête sous la forme {{baseUrl}}/api/Products/1. Changer d’environnement change toutes les requêtes d’un coup. Mettez aussi les tokens dans des variables, pour ne pas les copier dans des dizaines de requêtes.

Les tests dans Postman

Chaque requête a un onglet Tests (appelé Scripts, avec une section post-response, dans les versions récentes) où vous pouvez écrire du JavaScript qui s’exécute à l’arrivée de la réponse. Pour GET {{baseUrl}}/api/Products/1 :

Test Postman
pm.test("status is 200", function () {
  pm.response.to.have.status(200);
});

pm.test("product 1 has a price", function () {
  const product = pm.response.json();
  pm.expect(product.id).to.eql(1);
  pm.expect(product.price).to.be.a("number");
});

Les résultats apparaissent dans un onglet Test Results à côté de la réponse. Le Collection Runner peut ensuite lancer toutes les requêtes d’une collection et indiquer quelles vérifications ont échoué. C’est un premier pas en douceur vers l’automatisation. La leçon sur l’automatisation explique comment écrire les tests comme du code ordinaire, ce qui passe mieux à l’échelle au-delà de quelques dizaines.

Lequel utiliser

Les deux, pour des tâches différentes.

SituationMeilleur choix
Vérifier une chose rapidement, ou reproduire un rapport de bugcurl
Partager une requête exacte dans un ticket ou une discussioncurl (n’importe qui peut la coller et la lancer)
Explorer une API que vous ne connaissez pas encoreClient graphique avec l’import OpenAPI
De longs corps JSON que vous modifiez sans cesseClient graphique
Passer d’un serveur de test à la préproductionEnvironnements du client graphique
Exécuter dans un script ou sur un serveur de buildcurl, ou des tests écrits en code
Regarder les en-têtes bruts et les détails de connexioncurl -v

Une option de plus, propre à cette API : chaque page de point d’accès de la référence de l’API a un formulaire pour envoyer la requête et affiche une commande curl prête à copier. C’est souvent le moyen le plus rapide d’essayer un point d’accès avant de l’enregistrer quelque part.

  • Quand un rapport de bug contient une requête, joignez-la sous forme de commande curl. Le développeur peut la lancer sans rien importer, et il n’y a aucun doute sur les en-têtes envoyés.
  • Postman convertit dans les deux sens. Collez une commande curl dans la boîte Import pour obtenir une requête, ou utilisez le bouton Code d’une requête pour obtenir le curl.

Exercice

Faites ceci avec curl, puis recommencez dans un client graphique.

  • Envoyez GET /api/echo/headers et comparez les en-têtes envoyés par curl avec ceux de votre client graphique. Quels en-têtes chaque outil a-t-il ajoutés de lui-même ?
  • Créez une tâche avec POST /api/Todos, puis récupérez-la avec GET /api/Todos/ suivi de l’ID de la réponse.
  • Envoyez le même POST sans l’en-tête Content-Type. Quel statut et quel corps reviennent ?
  • Utilisez -w pour chronométrer /api/Products et /api/Products?delay=2. Le paramètre delay fait attendre le serveur : la seconde devrait prendre environ deux secondes de plus.

Dans votre client graphique, créez un environnement avec une variable baseUrl et écrivez un test qui échoue exprès, pour savoir à quoi ressemble un échec avant de vous fier à une réussite.

S’entraîner et aller plus loin