Déléguer une décision à un service
GuideExploitationDepuis la version 1.2.0
Guide d'exploitation : configurer, déployer et observer la passerelle. Ce que fait la capacité côté produit : guide produit ; l'appeler : guide développeur.
Objectif : laisser un service de son SI décider d'une requête (score de risque, droit métier) ou l'enrichir d'un en-tête - sans greffon dans la passerelle.
Commande - le service se déclare comme un amont, la politique le nomme :
upstreams:
risk: { url: http://risk.internal:8080 } # pool, cloisonnement, coupe-circuit : les siens
policies:
definitions:
risk-check:
type: external-call
phase: request # request : avant l'amont ; response : après sa réponse
config:
upstream: risk # un amont déclaré, jamais une URL
path: /score
timeout: 150ms # obligatoire, au plus le budget de l'opération
on_failure: fail-closed # obligatoire : fail-open | fail-closed
send: { headers: [X-Tenant], body: true }
deny: { when: "response.status == 403", status: 403, code: risk_refused }
set_headers: { X-Risk-Score: "response.body.score" }Vérif : un POST /orders que le service refuse reçoit 403 application/problem+json
(code: risk_refused) sans que l'amont le voie ; accepté, l'amont reçoit X-Risk-Score ;
flexway_policy_external_calls_total{policy="risk-check"} compte chaque appel par outcome (ok,
denied, failed_open, failed_closed) ; la trace montre un span external-call risk-check sous
celui de la requête.
| Règle | Ce qu'elle veut dire |
|---|---|
| Service déclaré | upstream nomme un amont de upstreams (HTTP, sans token_exchange), path un chemin littéral : aucune URL construite depuis la requête. L'appel est un POST |
| Ce qui part | Les en-têtes nommés par send.headers, pris dans la requête préparée pour l'amont (déclarés, tenant écrit par la passerelle) ; jamais Authorization ni un en-tête protégé. send.body : le corps de la requête, lu dans server.limits.max_body |
| Ce qu'il décide | deny (when sur la réponse, statut 4xx, code déclaré) ou set_headers (expressions CEL sur response.status et response.body, la réponse du service) - rien d'autre |
| Panne | Pas de réponse à temps, service injoignable, coupe-circuit ouvert, 5xx, réponse illisible pour une condition : fail-open continue sans la politique, fail-closed refuse (504, 503, 502) - jamais un défaut |
| Budget | L'appel consomme le budget de l'opération (x-flexway-timeout) : un service lent laisse moins de temps à l'amont, jamais plus de temps au total |
| Coupe-circuit | Le service est un amont : en panne, son circuit s'ouvre (Flexway-Degraded: circuit-open; upstream=risk) et la passerelle cesse de l'appeler |
| Refusé au chargement | Sans timeout ni on_failure ; timeout au-delà du budget ; un amont non déclaré ; un en-tête protégé dans set_headers ; send.body sur un flux ou en phase response ; gRPC, l'inférence - le message nomme l'opération et la politique |
| Simulation | /simulate n'appelle jamais le service : la politique n'y est pas appliquée |
Exemple complet : Appel externe.