Quand on développe une API REST, on peut la tester avec Swagger UI (intégré à notre application ou non) mais le plus souvent on utilise la commande curl
depuis le terminal.
curl
fonctionne très bien pour cela mais il existe une commande ligne qui simplifie considérablement les lignes de commandes à utiliser pour accéder à une API REST.
Cette commande se nomme httpie, est écrite en Python, et on va voir ici comment l’utiliser pour simplifier nos tests d’API REST.
1. Installer httpie
Sous Debian:
$ sudo apt-get install httpie
Et si on veut installer la complétion Bash
:
$ sudo curl -L https://raw.githubusercontent.com/httpie/httpie/master/extras/httpie-completion.bash -o /etc/bash_completion.d/httpie-completion
2. Un premier GET
Imaginons que l’on souhaite afficher la liste des brasseries de la base de données Open Brewery DB:
$ http GET https://api.openbrewerydb.org/breweries
Que l’on peut déjà simplifier par:
$ http https://api.openbrewerydb.org/breweries
Puisque seule l’URL est obligatoire.
On obtient alors:
HTTP/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-RAY: 5c6b95b16e9eee23-CDG
Cache-Control: max-age=86400, public
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
Date: Sat, 22 Aug 2020 09:32:07 GMT
Etag: W/"4af48ac4307f06c303db87af93a53748"
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
Set-Cookie: __cfduid=de3673bc734fb402d00db821fdf2792f81598088727; expires=Mon, 21-Sep-20 09:32:07 GMT; path=/; domain=.openbrewerydb.org; HttpOnly; SameSite=Lax; Secure
Strict-Transport-Security: max-age=31536000; includeSubDomains
Transfer-Encoding: chunked
Vary: Origin
Via: 1.1 vegur
X-Request-Id: adafd1e2-b5ed-42a3-9643-48e9f661c6ba
X-Runtime: 0.033734
cf-request-id: 04b71be2de0000ee2304ac1200000001
[
{
"brewery_type": "micro",
"city": "Birmingham",
"country": "United States",
"id": 2,
"latitude": "33.524521",
"longitude": "-86.774322",
"name": "Avondale Brewing Co",
"phone": "2057775456",
"postal_code": "35222-1932",
"state": "Alabama",
"street": "201 41st St S",
"updated_at": "2018-08-23T23:19:57.825Z",
"website_url": "http://www.avondalebrewing.com"
},
{
"brewery_type": "micro",
"city": "Birmingham",
"country": "United States",
"id": 44,
"latitude": "33.5128492349817",
"longitude": "-86.7914000624146",
"name": "Trim Tab Brewing",
"phone": "2057030536",
"postal_code": "35233-3401",
"state": "Alabama",
"street": "2721 5th Ave S",
"updated_at": "2018-08-23T23:20:31.423Z",
"website_url": "http://www.trimtabbrewing.com"
},
...
Si on l’ajoute le flag --body
, seulement le contenu utile est affiché. On peut aussi n’afficher que les Headers avec --headers
ou être plus verbeux avec --verbose
.
3. Un GET en mode verbeux
Avec le flag --verbose
, httpie
nous en dit un peu plus sur la requête qui est exécutée:
$ http --verbose https://api.openbrewerydb.org/breweries/253
GET /breweries/253 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: api.openbrewerydb.org
User-Agent: HTTPie/0.8.0
...
4. Authentification et réutilisation de session
Une fonctionnalité très utile de httpie
est la notion de session.
Lorsque les APIs REST nécessitent de s’authentifier, on a besoin de véhiculer dans nos requêtes un identifiant de session communiqué par l’API lors de la phase d’authentification.
Voyons comment on peut s’authentifier en Basic – même si ce n’est pas recommandé et que la fonctionnalité va bientôt disparaître – avec une requête GET sur GitHub:
$ http --session=github --auth "your_github_user:your_github_password" https://api.github.com
Je viens de faire une requête GET:
- En authentification basique (le défaut)
- En créant une session nommée github
Une fois authentifié, je peux voir la liste de mes dépôts privés en précisant la session que je viens ce créer avec --session=github
:
$ http --verbose --session=github https://api.github.com/user/repos
GET /user/repos HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Basic eW91cl9naXRodWJfdXNlcjp5b3VyX2dpdGh1Yl9wYXNzd29yZAo=
Connection: keep-alive
Host: api.github.com
User-Agent: HTTPie/0.8.0
...
Le mode --verbose
nous montre le Header Authorization
qui est véhiculé pour authentifier la requête.
5. Un exemple de POST d’authentification
Si votre backend permet de s’authentifier par une requête POST, vous pouvez le faire aussi simplement que cela:
$ http --session=ldap POST https://server1.lab1.lab.company.int/api/authentication/ < ldap.json
Avec dans le fichier d’entrée:
$ cat ldap.json
{
"username": "myuser",
"organization": "myCompany",
"password": "myPassword"
}
Ensuite, comme dans l’exemple précédent, la session nommée ldap
sera réutilisée pour les requêtes suivantes.
On peut aussi fournir les éléments du contenu sur la ligne de commande, sous la forme clé=valeur:
$ http --session=ldap POST https://server1.lab1.lab.company.int/api/authentication/ username=myUser organization=myCompany password=myPassword
6. Coloration syntaxique
Cela n’apparaît pas sur les exemples précédents, mais httpie
formate les documents .json
de sortie, rendant facultative l’utilisation de jq
, et colore la sortie pour plus de commodité.
On peut s’en rendre compte sur l’exemple fourni sur le site officiel:
7. Fichier de configuration
Lorsque vous utilisez des serveurs de test dont le certificat est autosigné, on doit préciser --verify=no
qui est l’équivalent du flag --insecure
de curl
.
Et plutôt que de le préciser sur chaque ligne de commande httpie
, on peut ajouter les paramètres par défaut dans le fichier de configuration situé ici: $HOME/.httpie/config.json
.
Par exemple:
$ cat .httpie/config.json
{
"default_options": [
"--style=fruity",
"--verify=no",
"--default-scheme=https"
]
}
Le dernier élément du tableau permettant d’omettre le début de l’URL: https:// dans les requêtes.
Note:
Il est possible que le fichier de configuration ne se trouve pas dans $HOME/.httpie mais plutôt dans $HOME/.config/httpie.
8. Complétion Bash
Un fichier de complétion Bash
existe pour httpie
mais il souffre des limitations suivantes:
- Certaines options sont manquantes
- Pas de complétion sur les méthodes HTTP: GET, POST …
- Pas de mécanisme pour compléter l’URL avec des noms d’hôtes connus comme ceux du fichier
/etc/hosts
Un outil complémentaire à httpie
existe, utile notamment pour l’aide à la complétion des URLs: http-prompt.
9. Conclusion
httpie
est un outil redoutable pour communiquer avec des Web Services ou des services REST.
Les lignes de commandes sont simples et compréhensibles, la coloration syntaxique aide grandement l’utilisateur et le mécanisme de session remporte l’adhésion.
Je vous invite à lire la documentation sur le dépôt GitHub du projet ou sur le site https://httpie.org/, vous verrez notamment ce que je n’ai pas abordé ici, à savoir comment:
- Ajouter un Header dans la requête
- Positionner un query string
- Simplifier l’URL pour
localhost
Je ne vois pas comment on peut encore utiliser curl
après avoir essayé httpie
!