flexway
FRENTalk to an expert

Reshaping a response

GuideOperationsSince version 1.2.0

Markdown

Operations guide: configure, deploy and observe the gateway. What the capability does, product side: product guide; calling it: developer guide.

Goal: serve only what the contract publishes, mask personal data, translate an upstream's non-standard statuses - without touching the upstream.

Command - three policies in flexway.yaml, attached to the operation or to routes:

policies:
  definitions:
    public-order:
      type: transform-body
      config: { project: [id, status, total, items, customer], on_missing: fail }   # a closed list; fail | omit
    no-pii:
      type: redact
      config: { fields: [body.customer.email, body.customer.phone], with: "***" }   # or remove: true
    legacy-errors:
      type: map-status
      config:
        - { from: 200, when: "has(body.error)", to: 422, code: legacy_rejected }    # a CEL condition on the body
        - { from: 520, to: 502 }

Check: GET /orders/7 returns the listed fields only, customer.email is "***"; a 200 carrying error arrives as a 422 application/problem+json (code: legacy_rejected), without the upstream's words; flexway_policy_executions_total{phase="response"} counts each policy applied, by operation, and flexway_policy_skipped_total the ones their condition skipped (1.2.0).

Rule What it means
Order map-status decides the status, then transform-body, then redact - whatever the chain's order
Cost The body of these operations is read whole (JSON only); every other keeps the direct relay
Successes projected transform-body touches 2xx only; redact masks every response, errors included
Error produced map-status to a 4xx/5xx: an RFC 9457 problem, the upstream's body dropped; to a success: the operation must declare it
Never raw Past server.body.max_bytes (1 MiB): 502 response_too_large; an unreadable or non-JSON body: 502 upstream_error - never served as it came
Circuit breaker It counts the upstream's status: a 503 served as 422 is still a failure
Refused at load A stream, a non-JSON response, gRPC, inference; a projection that drops a required field or keeps an undeclared one; a mask of the wrong type; a contract example that, transformed, no longer holds its schema - the message names the operation
Conformance server.body.validate_sample (0.01) of the served bodies validated against the contract: a departure counts flexway_policy_nonconformant_total, never a refusal; reloadable
Cache The cache keeps the upstream's answer; a hit is transformed as a miss is

Full example: Response body and status.

Next steps