Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Content-based routing (switch)

The switch structural endpoint picks one destination per message. Output only. It has two modes and uses exactly one of them: value lookup on a metadata key, or when predicates over the payload. Naming both is a startup error.

output:
  switch:
    metadata_key: "country_code"
    cases:
      US: { kafka: { topic: "us_orders", url: "kafka-us:9092" } }
      EU: { nats:  { subject: "eu_orders", url: "nats-eu:4222" } }
    default: { file: { path: "/var/data/unroutable_orders.log" } }

A message whose key is missing or unmatched goes to default; without a default it is dropped.

From the CLI, the same endpoint is a URI: switch:?metadata_key=country_code&case.US=<uri>&default=<uri> — see Structural endpoints in the URI.

Route on the payload (when)

when takes an ordered list of predicates and sends the message to the first one that matches. The expression language is the one --filter uses: payload fields by bare name including nested paths, metadata under meta., and and / or.

output:
  switch:
    when:
      - if: "amount > 10000"
        to: { kafka: { topic: "large_orders", url: "kafka:9092" } }
      - if: "order.status == 'refunded'"
        to: { nats: { subject: "refunds", url: "nats://localhost:4222" } }
    default: { file: { path: "/var/data/orders.jsonl" } }

A predicate parses the payload, while value lookup is a HashMap get on metadata — which is why the modes cannot be mixed in one endpoint, and why a metadata key you already have is the cheaper branch. A message matching no predicate goes to default, and without a default it is dropped, exactly as in value-lookup mode.

The CLI spells this as when=<expression> / to=<uri> pairs: switch:?when=amount > 10000&to=<uri>&default=<uri>.

Promote a payload value into metadata

Value-lookup mode matches on metadata, not payload fields. When you want that mode — an exact-match table rather than predicates — promote the value into metadata first. Two common ways:

  • An endpoint that already emits a status key — e.g. http_status_code from an HTTP request, or mongodb.outcome from a Mongo upsert (see Upserts).
  • transform with on_error: pass_through, which sets mqb.transform_error on failed records so you can shunt them aside:
output:
  middlewares:
    - transform: { schema_file: "schemas/order.json", on_error: pass_through }
  switch:
    metadata_key: "mqb.transform_error"
    cases: {}                                  # (no exact-match cases)
    default: { kafka: { topic: "orders", url: "localhost:9092" } }

Split HTTP responses by status

Pair switch with request, which forwards a response (or, on error/timeout, the original message) tagged with a status key:

output:
  request:
    to: { http: { url: "https://api.internal/score" } }
    forward_to:
      switch:
        metadata_key: "http_status_code"
        cases:
          "200": { nats: { subject: "ok", url: "nats://localhost:4222" } }
          "404": { file: { path: "not-found.jsonl" } }
        default: { file: { path: "other.jsonl" } }

See also Fan-out to send to all destinations instead of picking one.