Skip to content
Art2link ESB v2.02 LTS HomeDocumentationBlogContact
Core concepts/Adapters/API adapter
Adapter

API adapter

The HTTP transport. Hosts an endpoint when bound to a receive port, dispatches outbound requests when bound to a send port. Both directions support one-way and two-way modes.

ADAPTER · RECEIVE · SEND API HTTP transport, Listener on the receive side, Caller on the send side Shipping DIRECTION ↓ ↑ Receive & Send MODES One-way · Two-way AUTHENTICATION API Authentication PORT Receive or Send RESPONSE Payload

The API Listener (on a receive port) and API Caller (on a send port) are two selections in the UI; this article treats them as one adapter because the underlying protocol and configuration model are shared.

The split is direction, not function. A Listener has to expose an endpoint and accept inbound connections; a Caller has to reach out and manage connections, timeouts, and response handling. Splitting them in the platform lets each adapter focus on the work its side requires.

SAME PROTOCOL HTTP RECEIVE SIDE API Listener External RECEIVE PORT Exposes an endpoint accepts inbound connections Brings a message into the bus SEND SIDE API Caller SEND PORT Reaches outbound manages timeouts & response Endpoint Takes a message off the bus

Bound to a receive port, the API adapter turns the port into an addressable HTTP endpoint. External callers issue requests against the configured path; the adapter accepts them, runs the receive port's inbound stages, and publishes the resulting message to the bus.

Both modes are supported. One-way returns immediately after publishing; two-way holds the caller's connection open and waits for a matching response message on the bus.

One-way Caller API LISTENER request Bus 202 ACCEPTED Caller releases immediately. No reply correlated back. Webhooks, fire-and-forget ingestion. Two-way Caller API LISTENER request held Bus response message 200 OK + body Caller waits; response correlated. Match driven by Response Subscription Expression. Request/response APIs, synchronous lookups.

In two-way mode on the receive side, the adapter has to know which bus message is the response to the request it just received. That is the job of the receive port's Response Subscription Expression: a Boolean predicate the bus evaluates against every published message; the first match becomes the response delivered back to the caller.

The expression is evaluated in the same engine used by send/loopback/null port subscriptions, with one important addition: it can reference values that belong to the original inbound request. The most useful of these is a correlation token (a request id, a unique header, a generated GUID) assigned to a variable at the start of the receive port's inbound flow and matched on the outbound side of whichever port produces the response.

EXTERNAL CALLER POST /orders X-Req-Id: abc-123 API LISTENER · RECEIVE PORT two-way, holding connection VARIABLE CAPTURE corr := header(X-Req-Id) on the inbound side Bus request message published with promoted property: corr_id = "abc-123" downstream port processes; eventually publishes a response carrying the same corr_id DOWNSTREAM SEND PORT subscribes, processes, produces response Outbound: variables.copy(corr_id) -> response message Response is republished with promoted: corr_id = "abc-123" the value the listener will match on RESPONSE SUBSCRIPTION EXPRESSION evaluated on every publish {{Promoted.Response.corr_id}} == {{Variable.corr}} match: the response with this caller's correlation token ✓ MATCH → reply
If no message matches inside the request timeout, the caller receives a timeout status (typically 504) and the held connection is released. The bus state itself is unaffected, the in-flight messages are not rolled back. If a late response arrives after the timeout, it remains on the bus and is treated as an unsubscribed message.

Bound to a send port, the API adapter dispatches an HTTP request to a configured endpoint. The send port carries the request configuration (method, URL, headers, body) and the adapter handles the dispatch and response.

One-way mode fires the request and continues; the HTTP status is checked for success/failure but the response body is discarded. Two-way mode waits for the HTTP response and republishes it to the bus as a payload message, ready for a downstream port to subscribe to.

One-way Bus API CALLER request Endpoint Fire and continue. Status checked; response body discarded. Use when the response carries no value downstream. Two-way Bus API CALLER request Endpoint response republished Response becomes a bus message. Body and status are published as a payload; any port subscribing to it picks it up. Use when the response feeds the next step.

The send port configures the outbound request the API Caller will issue. URL, headers, and body are plain strings templated with {{…}} bindings: promoted properties, variables, constants, and {{Config.*}}. Body extractions ({{Message.Body}}.XPath) are not evaluated in adapter fields; promote the value on the message type or capture it into a variable and bind that.

METHOD GET POST PUT PATCH DELETE URL TEMPLATE https://api.partner.example/{{Variable.partner_id}}/orders/{{Promoted.Order.Id}} HEADERS X-Request-Id: {{Variable.correlation_id}} Content-Type: application/json Authorization: handled by the Authentication BODY { "order": "{{Promoted.Order.Id}}", "total": "{{Promoted.Order.Total}}"} leave blank for GET / DELETE

The API adapter pairs with an API Authentication, and the two directions take different Definitions, because direction decides who sets the rules: calling out, the remote API dictates how you must authenticate; listening, you dictate what callers must present:

  • Send side (API Caller): the Authentication presents credentials on the outbound request. The adapter injects them automatically, never set an Authorization header by hand on the Request Headers list; it will be overwritten.
  • Receive side (API Listener): the Authentication validates credentials presented by inbound callers. Where an Authentication is required and the inbound credential is missing or invalid, the listener returns 401 without invoking the rest of the receive port.

On the port, the pairing is made in the adapter configuration dialog through two fields. Auth Config Type chooses between Static, which pins the port to one named Authentication, and Dynamic, which resolves the Authentication name at runtime from a {{ }} binding, so a single port can present a different credential per message, one delivery port serving many partners, each with its own login, instead of a cloned port per login. Auth Config then holds the static pick or the dynamic expression.

A Listener’s Authentication is built on the API Listener Token Definition: its Partner Config section carries the Token inbound callers must present. A Caller’s Authentication is built on one of two Definitions, matching what the remote API demands. API Basic Authentication (Basic AuthConfig) carries a Username and Password. API Bearer Token (Bearer AuthConfig) carries a Login URL, Refresh Token URL, Token JSON Path, Refresh Token JSON Path, Username, and Password: the adapter logs in, lifts the token out of the login response with the JSON path, presents it as the Bearer Authorization header, and renews it through the refresh pair. Further shapes arrive as partner APIs demand them.

Every API Listener in the solution is hosted under the same base URL, there is one ingress for the whole environment. The path alone does not tell the runtime which receive port a request belongs to, so the listener routes on the inbound credential and headers instead. Three things together select the destination port:

  • The App header, whose value is the target Application’s namespace, this is what narrows an inbound request to one Application.
  • The Authentication presented on the request, the credential is part of the routing key, not just an access check.
  • Any additional matching headers the receive port declares, the tie-breaker described below.

The App header plus the Authentication is enough only while an Application has a single API Listener. The moment two API Listeners live in the same Application, that pair no longer distinguishes them, an inbound request would satisfy both, so each Listener must declare an extra header that makes it unique. The header name is your choice; a clear convention is a Purpose header with a per-port value, e.g. Purpose: Order on one and Purpose: Invoice on another.

That full combination, App namespace, Authentication, and any distinguishing headers, has to be unique. If two running receive ports declare the same combination, an inbound request matches both and the runtime cannot decide where to route it. To prevent it, the combination is validated for uniqueness across the whole system, not just within an Application, at the moment a port is started.

  • Stopped, allowed. A stopped port is inert and takes no part in routing, so a colliding combination can sit in a stopped port without conflict.
  • Start, blocked. Starting a port whose combination already belongs to another running port fails validation; the port stays stopped with nothing lost.
Exact-combination match. The check today compares the full App-plus-Authentication-plus-header combination for an exact duplicate. It does not yet catch overlapping combinations, e.g. one port matching X: 1 and another matching X: 1 plus Y: 2, where a request carrying both still satisfies both ports. Keep header match sets disjoint until overlap detection is added.

Fields differ by side. The Listener set matches the current dialog; the Caller set is still to be verified against the running product.

Receive side, API Listener
Auth Config Type, required; Dynamic or Static, see Authentication above.
Auth Config, required; the API Authentication, a named pick when Static, a {{ }}-resolved name when Dynamic.
Headers, required; key/value rows the inbound request must carry, the routing tie-breaker described under Routing on a shared ingress.
Verb, required; the HTTP method the endpoint accepts, e.g. POST.
Url, read-only; the shared ingress address every Listener in the environment is hosted under.
In two-way mode the listener holds the connection until a matching response message arrives or the platform’s wait window lapses; a configurable per-port request timeout is planned but not yet available.
Send side, API Caller
HTTP Method, required; one of GET, POST, PUT, PATCH, DELETE.
URL Template, required; absolute URL with optional {{…}} template tokens, promoted properties, variables, constants.
Request Headers, optional; one row per header. Values are templatable. The Authorization header is owned by the Authentication.
Request Body, optional; raw body or templated payload. Ignored for methods that do not carry a body.
Content-Type, optional shortcut; sets the Content-Type header without typing it in the Headers list.
Timeout (seconds), optional; per-request timeout.
Follow Redirects, optional toggle; default off.
Auth Config Type / Auth Config, required when the endpoint requires credentials; Static picks a named API Authentication, Dynamic resolves the name from a {{ }} binding.
i
The Response Subscription Expression is a property of the receive port, not the adapter. It is configured one screen over from the adapter binding because it applies whenever the port is two-way, regardless of which adapter the port is bound to. See the Receive port article for that field's reference.

That is the API adapter

HTTP transport, one adapter, two product objects. API Listener accepts, API Caller dispatches. Two-way correlation on the receive side via Response Subscription Expression; two-way payload return on the send side. Back to Adapters.