# examples/variables.yaml## Reference config for routing VARIABLES: per-request values derived from the# request path, a filtered header, and the JSON body fill {name} placeholders# in publish targets and in a webhook destination url.## The scenario: one Hookway instance in front of several environments# (qa-1, staging, prod, ...). The vendor is given one webhook URL per# environment, e.g. https://hooks.example.com/webhooks/qa-1/vendor, and each# event lands in that environment's pre-provisioned SQS queue and downstream# API.## Path placeholders on http_trigger (e.g. {envName}) are copied onto# envelope.Vars automatically. Body fields can be copied with a transform# field_map node. A code node can derive variables from filtered headers.# Unresolved templates and unsafe variable values fail closed at publish.server: addr: ":8080" max_body_bytes: 1048576security: # The code node below can inspect this routing header, but not the inbound # authentication token or any other unlisted header. forwarded_header_allowlist: [Content-Type, X-Hookway-Environment]destinations: environment_queues: type: sqs sqs: region: "us-east-1" downstream_api: type: webhook webhook: # The host is templated. A placeholder in the host must be followed by a # literal domain suffix so a request can never choose an arbitrary host. # The route target is appended as the final path segment. url: "https://{envName}-api.example.com/v1/events/webhook" timeout: "10s" auth: type: "api_key" header: "Authorization" value: "${DOWNSTREAM_API_KEY}" audit: type: mongodb mongodb: uri: "${MONGODB_URI}" database: "webhooks"flows: vendor: nodes: - {id: in, type: http_trigger, path: "/webhooks/{envName}/vendor", methods: [POST]} - {id: body, type: read_body, max_bytes: 1048576} - {id: auth, type: auth, scheme: exact, secret: "${VENDOR_WEBHOOK_TOKEN}", signature_header: X-Vendor-Token} - {id: env, type: envelope, body_format: json} - id: route type: code timeout: 50ms description: "Use a filtered header when present; otherwise keep the environment from the URL path." script: | const allowed = ['qa-1', 'staging', 'prod']; const requested = input.headers['X-Hookway-Environment'] || input.vars.envName; if (allowed.indexOf(requested) === -1) throw new Error('unknown environment'); return { body: input.body, vars: { envName: requested } }; - id: map type: transform kind: field_map mappings: - from: body.data.object.organizationId to: vars.tenant # envName comes from the allowlisted header or path; tenant is filled by # field_map. The queue must already exist, so an unknown environment does # not create infrastructure. Unresolved templates fail closed at publish. # DynamoDB lookup variable envByApp is omitted until the lookup node grows # those fields (index, filter, value_attribute, region). - {id: out_queue, type: publish, destination: environment_queues, target: "{envName}-events"} - {id: out_api, type: publish, destination: downstream_api, target: event} - {id: out_audit, type: publish, destination: audit, target: "{envName}-{tenant}"} edges: [in>body, body>auth, auth>env, env>route, route>map, map>out_queue, map>out_api, map>out_audit]