# Enrichir un flux

> Objectif : poser un en-tête, réécrire un chemin, ajouter un paramètre - sans toucher ni à l'amont ni au code de la passerelle.

Guide - Depuis la version 0.1.0 - Flexway v1.6.3 - https://flexway.io/docs/operations-policies/

> Guide d'exploitation : configurer, déployer et observer la passerelle. Ce que fait la capacité côté produit : [guide produit](https://flexway.io/docs/product-overview/) ; l'appeler : [guide développeur](https://flexway.io/docs/developer-overview/).

**Objectif** : poser un en-tête, réécrire un chemin, ajouter un paramètre - sans toucher ni à l'amont
ni au code de la passerelle.

**Commande** - une politique nommée dans `flexway.yaml`, attachée dans le contrat à **une**
opération :

```yaml
policies:
  definitions:
    enrich:
      type: header-inject
      when: "has(auth.subject)"            # CEL : seulement les appelants authentifiés
      config:
        set:
          x-plan: "{{ auth.claims.plan }}"   # une expression CEL entre accolades
        on_missing: skip                     # skip | empty | fail - obligatoire dès qu'une valeur est une expression
```

```yaml
paths:
  /orders/{id}:
    get:
      x-flexway-policies: [enrich]           # cette opération, et elle seule
```

Les niveaux s'additionnent - `policies.chains.global`, `.hosts.<hôte>`, `.routes."/orders/**"`,
puis l'opération - et **la plus précise gagne**. `!nom` retire une politique héritée :
`x-flexway-policies: ["!enrich"]`.

**Vérif** : l'amont reçoit `x-plan` sur `GET /orders/{id}` et sur aucune autre opération ;
`/config` (port d'administration) montre la chaîne de chaque opération sous `effective_chains`.
Une politique qui écrit un en-tête protégé - `Authorization`, `X-Forwarded-*`, la trace, l'en-tête
de tenant - **empêche le démarrage**.

> Les types de `0.1.0` : `header-inject`, `header-remove` (requête, réponse, refus),
> `rewrite-path`, `query-inject`, `query-remove`. Aucun ne lit le corps : un flux reste relayé sans
> tampon.

**Une valeur qui n'est pas du texte** dans un gabarit `{{ … }}` (`header-inject`, `query-inject`) se
rend toujours de la même façon :

| Valeur | Rendu |
| --- | --- |
| Texte | Tel quel ; `null` ou absente : rien (puis `on_missing` si l'expression échoue) |
| Nombre, booléen | Décimal, jamais en exposant (`1700000000`, pas `1.7e+09`) ; `true`, `false` |
| Liste | Éléments séparés par une virgule, la syntaxe de liste des champs HTTP (RFC 9110 §5.6.1) : `["seller","admin"]` -> `seller,admin` ; élément vide ou `null` omis ; élément liste ou objet en JSON |
| Objet | JSON compact, clés triées |

Pour un autre séparateur, `join` - la fonction de l'extension de chaînes de CEL, celle de
Kubernetes : `"{{ auth.claims.roles.join(' ') }}"` -> `seller admin`, `join()` sans séparateur. Une
liste qui contient autre chose que du texte fait échouer `join` : la valeur manque, `on_missing`
décide. Une fonction inconnue **refuse le chargement**. Un élément qui contient une virgule n'est
pas mis entre guillemets : choisir alors un autre séparateur avec `join`.
