Testez vos apis REST dans le terminal avec httpie

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 --verbosenous 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 !