# Chapitre 3 - Outils et fil rouge

# Bienvenue au bar API-ritif 🍹

Tout au long de ce cours, nous allons fréquenter un établissement très particulier : **API-ritif**, le bar de l'école de dev. On n'y entre pas par la porte, mais par HTTP.

<p class="callout info">L'adresse exacte du bar est donnée en cours.</p>

<p class="callout warning">Consommation responsable : les cocktails d'API-ritif sont 100 % virtuels.  
L'abus de requêtes est sanctionné par le barman (voir `429`).</p>

### La carte

<table id="bkmrk-cocktaildescription-"><thead><tr><th>Cocktail</th><th>Description du barman</th></tr></thead><tbody><tr><td>Hello World</td><td>Sans alcool. Le premier de tout développeur.</td></tr><tr><td>Null Pointer Mojito</td><td>Sans alcool : contient `null` alcool.</td></tr><tr><td>Segfault Sunrise</td><td>Un classique. Plante rarement, mais sans prévenir.</td></tr><tr><td>Pull Request Colada</td><td>Doux et crémeux. Nécessite deux approbations.</td></tr><tr><td>Blue Screen Lagoon</td><td>Bleu. Très bleu.</td></tr><tr><td>Java Martini</td><td>Un espresso martini. Long à démarrer, puis très efficace.</td></tr><tr><td>Merge Conflict</td><td>Deux alcools qui ne s'entendent pas. À résoudre à la main.</td></tr><tr><td>Kernel Panic</td><td>Le plus fort de la carte. Redémarrage conseillé après.</td></tr><tr><td>404 Spritz</td><td>Introuvable, comme son nom l'indique.</td></tr><tr><td>Sudo Rhum</td><td>Pour ceux qui ont les droits.</td></tr><tr><td>Infinite Loop</td><td>On en reprend un, puis un autre, puis un autre…</td></tr></tbody></table>

Le barman murmure qu'il existe d'autres cocktails, qui ne figurent pas sur la première page de la carte…

### Les règles de la maison

- Toutes les routes commencent par `/v1`.
- Le bar parle **JSON**. Pensez au header `Content-Type: application/json` quand vous envoyez des données.
- Les listes sont **paginées** : paramètres `?page=` et `?per_page=`.
- Certaines routes demandent d'être client du bar : envoyez votre clé dans le header `X-API-Key`.
- Les erreurs sont renvoyées au format `application/problem+json` : lisez-les, elles sont souvent bavardes.
- Le barman n'est pas une machine : trop de requêtes d'un coup et il vous demande de patienter.

### Les principales ressources

<table id="bkmrk-ressourcedescription"><thead><tr><th>Ressource</th><th>Description</th></tr></thead><tbody><tr><td>`/v1/`</td><td>L'accueil du bar</td></tr><tr><td>`/v1/customers`</td><td>Les clients (inscription)</td></tr><tr><td>`/v1/me`</td><td>Votre profil</td></tr><tr><td>`/v1/cocktails`</td><td>La carte</td></tr><tr><td>`/v1/cocktails/{id}/reviews`</td><td>Les avis sur un cocktail</td></tr><tr><td>`/v1/orders`</td><td>Vos commandes</td></tr></tbody></table>

La documentation complète de l'API (le contrat OpenAPI) sera étudiée au chapitre 6. D'ici là, explorez !

### La vie d'une commande

Une commande ne reste pas figée : elle avance toute seule dans le temps.

```text
pending ──▶ preparing ──▶ ready ──▶ served
   │
   └──▶ cancelled   (uniquement tant qu'elle est pending)
```

<p class="callout success">Comme dans un vrai bar : une fois que le barman a commencé à préparer la commande, il est trop tard pour annuler !</p>

# curl, Bruno et Postman

Pour parler à une API, pas besoin d'écrire du code : des outils permettent d'envoyer des requêtes HTTP à la main.

### curl

`curl` est l'outil en ligne de commande de référence. Il est installé par défaut sur Linux, macOS et Windows 10+.

```bash
curl http://api-ritif.portlatch.com/v1/cocktails
```

#### Les options utiles

<table id="bkmrk-optionr%C3%B4le--iaffiche"><thead><tr><th>Option</th><th>Rôle</th></tr></thead><tbody><tr><td>`-i`</td><td>Affiche les headers de la réponse</td></tr><tr><td>`-v`</td><td>Mode verbeux : affiche toute la requête et toute la réponse</td></tr><tr><td>`-X METHODE`</td><td>Choisit la méthode HTTP (`-X DELETE`)</td></tr><tr><td>`-H "Nom: valeur"`</td><td>Ajoute un header</td></tr><tr><td>`-d '...'`</td><td>Envoie un body (et passe en `POST` par défaut)</td></tr><tr><td>`--json '...'`</td><td>Envoie du JSON, avec les headers `Content-Type` et `Accept` adaptés</td></tr><tr><td>`-s`</td><td>Mode silencieux (masque la barre de progression)</td></tr></tbody></table>

#### Exemples

```bash
# Lire les headers de la réponse
curl -i http://api-ritif.portlatch.com/v1/cocktails/3

# Envoyer du JSON
curl -i -X POST http://api-ritif.portlatch.com/v1/orders \
  -H "Content-Type: application/json" \
  -H "X-API-Key: votre-cle" \
  -d '{"cocktail_id": 3}'

# La même chose, en plus court
curl -i http://api-ritif.portlatch.com/v1/orders \
  -H "X-API-Key: votre-cle" \
  --json '{"cocktail_id": 3}'

# Supprimer
curl -i -X DELETE http://api-ritif.portlatch.com/v1/orders/42 -H "X-API-Key: votre-cle"
```

<p class="callout info">Pour rendre le JSON lisible, passez la réponse dans un formateur : `curl -s ... | python3 -m json.tool` ou `curl -s ... | jq`.</p>

<p class="callout warning">Sous Windows PowerShell, `curl` peut être un alias vers `Invoke-WebRequest`, qui n'a pas les mêmes options. Utilisez `curl.exe`, ou Git Bash.</p>

<p class="callout warning">Plutôt que de copier votre clé dans chaque commande, stockez-la dans une variable : `export KEY=votre-cle`, puis `-H "X-API-Key: $KEY"`.</p>

### Bruno

[Bruno](https://www.usebruno.com) est un client d'API graphique, open source et sans compte. On y enregistre ses requêtes dans des **collections**.

Sa particularité : une collection est un **dossier de fichiers texte**. On peut donc la versionner dans git et la partager avec son équipe comme du code.

#### Prise en main

- Installez Bruno depuis [usebruno.com/downloads](https://www.usebruno.com/downloads).
- Créez une collection `api-ritif` dans un dossier de votre choix.
- Créez un **environnement** avec deux variables : `baseUrl` = `http://api-ritif.portlatch.com/v1` et `apiKey` = votre clé.
- Créez une requête `GET {{baseUrl}}/cocktails` et envoyez-la.
- Dans l'onglet **Headers** d'une requête, ajoutez `X-API-Key: {{apiKey}}`.

### Et Postman ?

Postman est le client d'API le plus connu, et vous le croiserez sûrement en entreprise. Il fonctionne sur le même principe que Bruno.

<p class="callout info">On ne l'utilise pas dans ce cours : il demande un compte, et stocke les collections dans son cloud plutôt que dans votre dépôt git.</p>

# TP : La chasse au trésor

### Objectif

Le barman d'API-ritif a caché un trésor quelque part dans son API. Pour le trouver, il faudra lire attentivement chaque réponse : codes de statut, headers, body… Rien n'est là par hasard.

Chaque étape franchie vous donne un **flag** : il se trouve dans le **header de la réponse** (`X-Flag`). Il y a **9 flags** à activer.

<p class="callout warning">TP noté, utilisation de curl ou bruno au choix</p>

### Consignes

#### Règles du jeu

<p class="callout warning">Inscrivez-vous avec le pseudo **`prenom-nom`**, sans accents ni espaces (ex. : `helene-dupre`). C'est lui qui permet au formateur de vous noter : un pseudo fantaisiste, c'est un TP sans note.</p>

- Chaque réponse de l'API contient l'indice qui mène à l'étape suivante (header `X-Hint`). Lisez **tout**, y compris les headers (`curl -i`).
- Quand vous franchissez une étape, la réponse contient son **flag dans le header `X-Flag`**, pas dans le body. Sans `curl -i`, vous ne verrez ni les flags ni les indices.
- Dès que vous avez une clé d'API, soumettez chaque flag trouvé : ```bash
    curl -i http://api-ritif.portlatch.com/v1/hunt/flag \
      -H "X-API-Key: $KEY" \
      --json '{"code": "RITIF-XXXX-XXXXXXXX"}'
    ```
- Les flags se valident **dans l'ordre**, et ne s'échangent pas : chaque flag (sauf le premier) est lié à votre clé.

<p class="callout info">Bloqué ? Relisez la page des codes de statut et celle des verbes HTTP. Un message d'erreur est souvent un indice.</p>

#### Les 9 flags à activer

Chaque étape ci-dessous renvoie un flag dans le **header de la réponse**. Soumettez-les dans cet ordre :

1. Lire les headers de l'accueil du bar.
2. Vous inscrire comme client du bar.
3. Vous présenter au barman : d'abord sans clé, puis avec.
4. Trouver le cocktail secret de la carte et le consulter.
5. Commander un thé.
6. Commander un cocktail et suivre sa commande jusqu'à ce qu'elle soit prête.
7. Annuler une commande à temps. Découvrez au passage ce que répond `OPTIONS`.
8. Obtenir un cocktail en XML.
9. Faire déborder le barman jusqu'au `429`, respecter le délai demandé, puis refaire une requête.

#### Point de départ

Tout commence à l'accueil du bar :

```bash
curl -i http://api-ritif.portlatch.com/v1/
```

Le reste, c'est à vous de le trouver. Santé ! 🍹