Skip to content

Migrating from reactor http to egresses ​

Egresses are Hantera's typed, ACL-gated outbound-traffic primitive. They replace ad-hoc outbound calls made with the reactor http module together with the legacy registry/security/allowedHosts whitelist.

The legacy http module remains available for back-compat, but new components should prefer egresses: a single typed call site, a tenant-scoped ACL, and — for rules — the ability to make a safe blocking call inline.

What changes ​

BeforeAfter
Reactor calls web.http directlyAn egress component performs the call; callers use the call filter
Host allowed via registry/security/allowedHostsThe existence of the egress resource is the host whitelist
Any component with the reactor runtime could reach the hostOnly callers granted egresses/<key>:call may reach it
Rules could not make HTTP calls at allRules may call egresses marked idempotent: true

Recipe ​

1. Move the HTTP call into an egress component ​

Take the body of your reactor's http call and put it into a new .hegress / .heg component. It imports http (in scope only in the egress runtime), declares the caller's request fields as params, and returns the result via a single from.

filtrera
//// components/egresses/createSession.hegress

import 'http'
import 'json'

param configurationId: text
param toAddress: {
  name: text
  address1: text
  postalCode: text
  city: text
  country: text
}

let config = registry 'apps/my-app'

from
  let res = http {
    method = 'POST'
    url = $'{config->''baseUrl''}/checkouts'
    headers = {
      'Content-Type' -> 'application/json'
      'X-Api-Key' -> config->'clientSecret'
    }
    body = { configurationId = configurationId, toAddress = toAddress } asJson
  }
  res.status match
    200 |> res.body parseJson
    |> { error = { code = $'http_{res.status}', message = res.body } }

2. Declare an egress resource in h_app.yaml ​

The resource binds a key to the component, sets the idempotency gate, and carries the ACL.

yaml
egresses:
  - id: createSession
    componentId: components/egresses/createSession.hegress
    idempotent: true

Mark idempotent: true only if repeated identical calls have the same observable effect as a single call. Idempotent egresses may be called from rules; non-idempotent egresses may only be called from reactors and jobs.

3. Replace the web.http call with call ​

Put the request payload on the left and the fully qualified egress key on the right.

filtrera
from
  { configurationId = '...', toAddress = { ... } }
  call 'apps/my-app/createSession'

call returns the egress component program's result directly. There is no envelope wrapper — transport and business errors flow through the component's own result convention (by convention { error = { code, message } }).

4. Drop the allowedHosts entry ​

Once all outbound traffic to a host goes through egresses, the host no longer needs an allowedHosts entry — the egress resource is the whitelist. Remove the entry unless a remaining legacy http-module component still needs it.

Wrapping a raw URL with platform/http ​

If you don't need a typed component, install a resource that binds the built-in platform/http component and pins the destination with a parameter override so callers cannot redirect the request:

yaml
egresses:
  - id: shopfront-webhook
    componentId: platform/http
    idempotent: true
    parameters:
      url: https://shop.example.com/hooks/order-created

parameters holds literal overrides keyed by the component's param names. For dynamic values (secrets, base URLs), read them inside the egress component via the registry-> macro rather than pinning them on the resource.

filtrera
from
  {
    method = 'POST'
    headers = { 'Content-Type' -> 'application/json' }
    body = { orderId = order.id, total = order.total } asJson
  }
  call 'my-app/shopfront-webhook'

Permissions ​

A caller must hold egresses/<egressKey>:call to invoke an egress, and this is never granted implicitly — list it explicitly in the calling component's ACL, whether the egress belongs to the same app or another. The class-level wildcard egresses:call grants the ability to call every egress.

Offline type-checking ​

The Hantera Development Studio type-checks both .hegress/.heg components and every call '<key>' against the egresses declared in the open app's h_app.yaml. No tenant connection is required — a manifest declaration is sufficient for full local validation.

© 2026 Hantera AB. Org. no.: 559242-9582