Aller au contenu
Nicolas Demay
Le client HTTP de JetBrains : testez vos API sans quitter votre IDE

Le client HTTP de JetBrains : testez vos API sans quitter votre IDE

Publié le 6 min de lecture

Quand on développe une API, le réflexe classique, c’est d’ouvrir Postman, ou plus récemment Bruno, pour envoyer quelques requêtes et vérifier que tout fonctionne. Ça marche, mais ça implique un changement de contexte permanent. On code dans PhpStorm, on alt-tab vers Postman, on revient, on re-tab…

Vous ne savez peut-être pas que tous les IDE JetBrains (PhpStorm, IntelliJ, WebStorm, GoLand…) embarquent un client HTTP complet, directement dans l’éditeur. Des fichiers .http versionnés avec le projet, exécutables en un clic, avec variables d’environnement, scripts, support GraphQL et autocomplétion OpenAPI.

Je l’utilise au quotidien depuis plus de deux ans, et je n’ai aucune envie de revenir en arrière.

Les bases : GET, POST et headers

On crée un fichier .http (ou .rest) n’importe où dans le projet. La syntaxe est minimaliste :

api-tests.http
### Liste des utilisateurs
GET http://localhost:8080/api/users
Accept: application/json

Pour un POST avec un body JSON, on ajoute simplement le contenu après une ligne vide :

api-tests.http
### Créer un utilisateur
POST http://localhost:8080/api/users
Content-Type: application/json
{
"name": "Nicolas Demay",
"email": "[email protected]"
}

Les headers se placent juste après la ligne de requête, sans ligne vide entre eux. Le séparateur ### permet d’enchaîner plusieurs requêtes dans le même fichier et de les nommer pour s’y retrouver.

api-tests.http
### Authentification
POST http://localhost:8080/api/login
Content-Type: application/json
{
"username": "admin",
"password": "secret"
}
### Récupérer le profil (requête protégée)
GET http://localhost:8080/api/profile
Authorization: Bearer {{auth_token}}
Accept: application/json

On lance chaque requête individuellement via l’icône play en marge, ou toutes d’un coup. La réponse s’affiche dans un panneau dédié avec le status code, les headers, et le body formaté.

D’ailleurs, petit tips : si vous avez une requête XHR qui pose problème dans le navigateur, clic droit dans les DevTools → “Copy as cURL”, puis collez directement dans un fichier .http. L’IDE convertit le cURL en syntaxe HTTP Client automatiquement. Pas besoin de réécrire les headers à la main.

Variables et environnements

On définit des environnements dans un fichier http-client.env.json, soit à la racine du projet, soit dans le même dossier que le fichier .http :

http-client.env.json
{
"dev": {
"host": "http://localhost:8080",
"api_version": "v1"
},
"staging": {
"host": "https://staging.example.com",
"api_version": "v1"
},
"production": {
"host": "https://api.example.com",
"api_version": "v2"
}
}

Les secrets vont dans un fichier séparé http-client.private.env.json (à ajouter dans le .gitignore, on a tous déjà pushé un token sur un repo public au moins une fois) :

http-client.private.env.json
{
"dev": {
"api_token": "dev-token-xxx"
},
"staging": {
"api_token": "staging-token-yyy"
}
}

Et dans les requêtes, on utilise la syntaxe {{variable}} :

api-tests.http
### Liste des produits
GET {{host}}/api/{{api_version}}/products
Authorization: Bearer {{api_token}}
Accept: application/json

Avant d’exécuter, un dropdown en haut de l’éditeur permet de choisir l’environnement cible. Les valeurs du fichier privé écrasent celles du fichier partagé. Du coup, l’équipe partage les URLs et la structure, chacun garde ses propres tokens.

Sélection de l'environnement dans le dropdown Run with du client HTTP JetBrains

L’IDE fournit aussi des variables dynamiques prêtes à l’emploi :

api-tests.http
### Créer une ressource avec un ID unique
POST {{host}}/api/items
Content-Type: application/json
{
"id": "{{$uuid}}",
"createdAt": "{{$isoTimestamp}}",
"priority": {{$randomInt}}
}

Pre-request et response handlers

Les response handlers (avec >) s’exécutent après la réponse et permettent de tester des assertions ou de stocker des valeurs :

api-tests.http
### Login et stockage du token
POST {{host}}/api/login
Content-Type: application/json
{
"username": "admin",
"password": "{{password}}"
}
> {%
client.test("Login réussi", function() {
client.assert(response.status === 200, "Status attendu : 200");
});
// Store the token for subsequent requests
client.global.set("auth_token", response.body.token);
%}

Le token est maintenant accessible via {{auth_token}} dans toutes les requêtes suivantes. On peut enchaîner les appels avec des dépendances de données.

Les pre-request scripts (avec <) s’exécutent avant l’envoi et permettent de préparer les données :

api-tests.http
< {%
// Generate a signature before sending
const timestamp = Date.now().toString();
request.variables.set("timestamp", timestamp);
request.variables.set("requestId", $random.uuid);
%}
POST {{host}}/api/secure
Content-Type: application/json
X-Timestamp: {{timestamp}}
X-Request-Id: {{requestId}}
{
"data": "payload"
}

Bref, on a client.log() pour débugger et client.test() pour créer de vraies suites de tests. Rien de révolutionnaire, mais ça fait le boulot sans quitter l’éditeur.

Upload de fichiers

Pour envoyer un fichier dans une requête, on utilise la syntaxe < suivie du chemin :

api-tests.http
### Upload simple (body = contenu du fichier)
POST {{host}}/api/import
Content-Type: application/json
< ./data/import.json
### Upload multipart (formulaire avec fichier)
POST {{host}}/api/upload
Content-Type: multipart/form-data; boundary=boundary
--boundary
Content-Disposition: form-data; name="file"; filename="document.pdf"
Content-Type: application/pdf
< ./files/document.pdf
--boundary
Content-Disposition: form-data; name="description"
Mon fichier uploadé
--boundary--

Attention : < lit un fichier en entrée (dans le body), > est réservé aux response handlers. Ne pas confondre les deux.

Support GraphQL

Le client HTTP supporte nativement GraphQL avec le mot-clé GRAPHQL :

graphql-tests.http
### Query
GRAPHQL {{host}}/graphql
query {
users {
id
name
email
}
}
### Mutation avec variables
GRAPHQL {{host}}/graphql
mutation ($input: CreateUserInput!) {
createUser(input: $input) {
id
name
}
}
{
"input": {
"name": "Nicolas",
"email": "[email protected]"
}
}

Et si l’IDE connaît déjà votre API ?

Si le projet contient une spécification OpenAPI (ou si on pointe vers un fichier distant), l’IDE s’en sert pour enrichir les fichiers .http :

  • Autocomplétion des URLs : les endpoints définis dans la spec sont suggérés pendant la frappe
  • Autocomplétion du body JSON : les champs requis sont proposés automatiquement

Même principe côté GraphQL : il faut installer le plugin GraphQL (gratuit sur le Marketplace JetBrains). Une fois activé, il introspecte le schéma de l’endpoint et propose l’autocomplétion sur les types, les champs et les arguments directement dans le fichier .http.

C’est là que l’avantage sur Postman est le plus net : l’IDE connaît déjà le code et la doc API. Pas d’import manuel, pas de synchronisation à maintenir.

Le vrai gain : le debug en un clic

C’est peut-être l’avantage le moins visible, mais celui qui me fait gagner le plus de temps. Quand on développe une API dans PhpStorm, on peut poser un point d’arrêt Xdebug dans le code, puis relancer la requête HTTP en un seul clic.

Pas besoin de retourner dans le fichier .http à chaque fois. Le bouton play en haut de l’IDE garde en mémoire la dernière commande exécutée — que ce soit un test unitaire ou une requête HTTP. On modifie le code, on pose un breakpoint, on clique sur play, et on est directement dans le debugger avec la bonne requête. Le cycle éditer → tester → débugger tient en quelques secondes, sans changer de fenêtre.

Avec Postman, ce workflow est cassé : il faut alt-tabber, relancer, revenir. Ici, tout reste dans le même écran.

Et avec l’IA dans la boucle ?

Le vrai bonus de ce format, c’est que les fichiers .http vivent dans le repo comme n’importe quel fichier de code. Versionnés, lisibles, partageables. Et du coup, un assistant comme Claude y a accès directement dans le contexte du projet.

En pratique, je lui demande régulièrement de me générer une requête .http pour tester un endpoint que je viens de créer. Il connaît le code, il connaît le schéma — le fichier est prêt en quelques secondes. Essayez de faire ça avec une collection Postman.