flexway
FRENTalk to an expert

Asynchronous

The asynchronous world, behind the same doors.

Publish to Kafka, AMQP or MQTT from HTTP, under an AsyncAPI contract, with the same identity and quotas as everything else; signed, replayable outgoing webhooks.

8 of the 9 shown delivered · since v1.5.0

What you expect from this domain

  • Control downstream commandsSparkplug commands under a declared scope planned; the condition on the current state of the system: candidatePartly · next in 1.7
  • Out-of-range device dataSchema minimum and maximum bounds on validated payloads; clinical rules stay with the servicePartly · next to be scheduled
  • Irrigation, machines: AI loop -> physical commandCommand authorised by scope (1.7.0); condition on the real state: candidate; physical safety systems stay independentPartly · next to be scheduled
Every market expectation
Asynchronous doors in the catalogueAsynchronous doors in the catalogue
Asynchronous doors sit in the catalogue next to the REST routes: one publishes to a topic, the other receives the events.Real console capture, demo data · v1.6.3

What it solves

Problem 1

Every team opens its own broker

Producers plugged straight into Kafka, with no contract or quota.

Flexway's answer: A channel exists only if the AsyncAPI declares it; publishing goes through the gateway.

Problem 2

The synchronous boundary breaks

An HTTP client waits for an answer a consumer will process later.

Flexway's answer: The gateway answers 202 with an id and publishes in a CloudEvents envelope.

Problem 3

A webhook is lost or forged

The receiver can neither check the origin nor replay.

Flexway's answer: Signed, replayable webhooks, under the same audit.

How it works

Every step is a decision readable in the trace and in the console.

Your infrastructureflexwayAPI, AI and agent gatewayUnified Decision Chain (UDC)undeclared channel: refused01 Contract02 Identity03 Quota04 Envelope05 Broker06 AnswerHTTP applicationsPartnersKafkaAMQP, MQTTWebhooksYour infrastructureflexwayAPI, AI and agent gatewayUnified Decision Chain (UDC)01 Contractchannel declared in the AsyncAPI02 Identityas for REST03 Quotaper caller04 EnvelopeCloudEvents 1.005 BrokerKafka, AMQP, MQTT06 Answer202 and an idHTTP applicationsPartnersKafkaAMQP, MQTTWebhooks

Asynchronous - Domain diagram: who calls, the decision steps, what is called, and where a request is refused.

  • HTTP applications
  • Partners
  1. Contract
  2. Identity
  3. Quota
  4. Envelope
  5. Broker
  6. Answer
  • Kafka
  • AMQP, MQTT
  • Webhooks

undeclared channel: refused

HTTP applications
The applications that call your APIs: each request goes through Flexway, which checks the contract and the identity before reaching your systems.
Partners
The partner companies that consume your APIs: identified by a client certificate or an API key, under a quota per tenant.
Contract
The channel must be declared in the AsyncAPI contract; an undeclared channel is refused before any publication.
Identity
Flexway checks who is calling (OIDC token, API key or client certificate) and reads the tenant from the identity; no valid identity: 401.
Quota
A token bucket per caller limits its rate; beyond it: 429 with Retry-After and the RateLimit headers.
Envelope
The message is put in a CloudEvents 1.0 envelope, so every consumer reads it the same way.
Broker
Flexway publishes the message on your Kafka, AMQP or MQTT broker, as a client of that broker.
Answer
The caller gets a 202 with an identifier: the message is accepted, what follows is asynchronous.
Kafka
Your Kafka cluster: Flexway publishes on it the events received over HTTP, under contract, in a CloudEvents envelope.
AMQP, MQTT
Your AMQP and MQTT brokers: Flexway publishes on them as a client of the broker, under an AsyncAPI contract.
Webhooks
Your partners' systems: they receive your events as signed, replayable webhooks.
  • Line: one route
  • Interchange: shared decision
  • Event
  • Refusal
  • Your infrastructure
  1. Contractchannel declared in the AsyncAPI
  2. Identityas for REST
  3. Quotaper caller
  4. EnvelopeCloudEvents 1.0
  5. BrokerKafka, AMQP, MQTT
  6. Answer202 and an id

In detail

The essentials of each topic, with its status in the published release; unfold a card for the full text.

AsyncAPI as the contract of the asynchronous plane

Delivered · v1.5.0

The asynchronous plane has its AsyncAPI 3.0 or 3.1 contract: what is published or consumed is exactly what is declared, checked at load.

  • AsyncAPI 3.0 and 3.1, official schema embedded
  • Published or consumed = declared
  • HTTP entry points x-flexway-publish and x-flexway-subscribe
See the detailHide the detail - AsyncAPI as the contract of the asynchronous plane

The asynchronous plane has its contract, just as the synchronous one has OpenAPI: contracts.asyncapi loads an AsyncAPI 3.0.0 or 3.1.0 document, validated against the embedded official schema. Channels, their messages and their schemas come from the contract; a send or receive operation names its broker with x-flexway-upstream. The HTTP entry point is an OpenAPI operation marked x-flexway-publish or x-flexway-subscribe.

The invariant stays the same: published or consumed = declared. An operation with no broker, an entry point to a missing operation or one in the opposite direction, a body with a different schema from the message, or a message without a JSON schema (Avro, Protobuf) are refused at load, all reported in one pass. A refusal is stated, never ignored.

All the points

  • AsyncAPI 3.0 and 3.1, official schema embedded
  • Published or consumed = declared
  • HTTP entry points x-flexway-publish and x-flexway-subscribe
  • Contract errors reported at load

Features and status

  • AsyncAPI as the source of the asynchronous planeDelivered · v1.5.0
Read in the documentation : Asynchronous plane and brokers

Publishing from HTTP: 202 after the broker acknowledges

Delivered · v1.5.0

An HTTP client publishes without a broker client: the body is validated, wrapped in CloudEvents, and the gateway answers 202 only after the broker acknowledges.

  • Body validated against the message schema
  • 202 only after the broker acknowledges
  • Bounded buffer: immediate 503 rather than an endless queue
See the detailHide the detail - Publishing from HTTP: 202 after the broker acknowledges

An HTTP client, or an agent through an MCP tool, publishes without embedding a broker client. The body is read in full within a bound, checked against the message schema, then wrapped in CloudEvents 1.0 binary mode (structured on MQTT 3.1.1). The gateway answers 202 only after the broker acknowledges: acks=all from an idempotent Kafka producer, AMQP confirms, MQTT PUBACK at QoS 1. An Idempotency-Key becomes the event id, and idempotency: required makes it mandatory (428 otherwise).

The buffer is bounded per broker and per replica (max_in_flight, 1,024 by default): beyond it, an immediate 503 overloaded, never a queue that grows with the outage. A circuit breaker per broker gives 503 upstream_unavailable; exceeding the budget gives 504 upstream_timeout, meaning the outcome is unknown.

The gateway authenticates to the broker (SASL, mTLS, secrets by reference); the caller travels as CloudEvents attributes - tenant always, traceparent, authid and authtype only if the message declares them - and a ce-* header supplied by the caller is refused (400). A message published through a REST route carries the same audit line and the same authorisation verdict as a synchronous call.

All the points

  • Body validated against the message schema
  • CloudEvents 1.0 envelope
  • 202 only after the broker acknowledges
  • Bounded buffer: immediate 503 rather than an endless queue

Features and status

  • Kafka publishing under contract, CloudEvents envelopeDelivered · v1.5.0
  • Mediation of the synchronous to asynchronous boundaryDelivered · v1.5.0
  • Projection to gRPC and to a broker messageDelivered · v1.5.0
Read in the documentation : Publishing and subscribing

Consuming over SSE or WebSocket, isolated per tenant

Delivered · v1.5.0

Browsers and mobiles consume a stream over SSE or WebSocket without speaking the broker's protocol, each subscriber receiving only what its verified values name.

  • Fan-out SSE, resumption via Last-Event-ID
  • At-least-once WebSocket, explicit acknowledgement
  • Isolation by verified values, never by content
See the detailHide the detail - Consuming over SSE or WebSocket, isolated per tenant

A browser or a mobile app consumes a stream without speaking the broker's protocol. Over SSE, delivery fans out: one consumer per channel and per replica, whatever the number of subscribers; resumption uses Last-Event-ID from the channel's in-memory history (history, 64 by default), with 412 beyond it. Over WebSocket, delivery is at least once: the position advances only after {"ack": "<id>"}, otherwise the connection is closed after ack_timeout and the message is delivered again.

A subscriber receives only what its verified values name: a bound channel parameter (x-flexway-bind: tenant, subject or claim:<name>) or the tenant attribute filtered on headers, never on data. A channel that is neither bound, nor filtered, nor declared public is refused at load. Public access is declared explicitly (x-flexway-public: true on the receive operation) and is still counted per address and overall.

The buffer is bounded per stream, a subscriber that is too slow is closed, and max_streams caps streams per caller and per replica (429 too_many_streams). Durable state - positions, groups - stays in the broker: the gateway remains stateless. Subscribing an agent to a stream through an MCP tool is upcoming.

All the points

  • Fan-out SSE, resumption via Last-Event-ID
  • At-least-once WebSocket, explicit acknowledgement
  • Isolation by verified values, never by content
  • Public only when declared

Features and status

  • Mediation of the synchronous to asynchronous boundaryDelivered · v1.5.0
Read in the documentation : Publishing and consuming on a broker

Kafka, AMQP and MQTT under the same admission

Delivered · v1.5.0

Kafka, AMQP and MQTT go through the same admission as HTTP traffic (identity, quota, audit, trace), the gateway reaching each broker as a client.

  • Kafka, AMQP 0-9-1, AMQPS and MQTT
  • Broker reached as a client, never relayed
  • SASL and mTLS, secrets by reference
See the detailHide the detail - Kafka, AMQP and MQTT under the same admission

Kafka, AMQP 0-9-1 (and AMQPS) and MQTT go through the same admission as HTTP traffic: identity, quota, audit, trace. The gateway reaches a broker as a client, never through a broker listener, and a contract operation is never relayed as is to a broker. Upstreams are declared with upstreams.*.protocol (kafka, amqp, mqtt), with brokers, protocol_version and sasl, whose password is a reference.

On consumption, both CloudEvents modes are read according to each binding's rule: application/cloudevents+json as structured, binary otherwise. Errors on the asynchronous plane are expressed as a CloudEvents attribute, as they are expressed in RFC 9457 over HTTP. The configuration reloads hot: an unchanged broker client is reused, and one client per subscription costs connections, hence the max_streams cap.

All the points

  • Kafka, AMQP 0-9-1, AMQPS and MQTT
  • Broker reached as a client, never relayed
  • SASL and mTLS, secrets by reference
  • Hot reload, unchanged clients reused

Features and status

  • AMQP(S) and MQTTDelivered · v1.5.0
  • Translation to the JSON-RPC error (MCP) and to the CloudEvents attribute (asynchronous)Delivered · v1.5.0
Read in the documentation : Examples: Kafka, RabbitMQ, MQTT, Avro, NATS, AMQP 1.0

Signed, replayable outbound webhooks

Delivered · v1.5.0

A receive operation delivers a tenant's events to a declared target, signed in the Standard Webhooks format, with bounded retries and a replayable dead-letter queue.

  • Standard Webhooks, HMAC-SHA256, two-secret rotation
  • Address checked at connection, no redirect
  • At least once, dead-letter queue mandatory
See the detailHide the detail - Signed, replayable outbound webhooks

A receive operation can deliver to a declared target (x-flexway-deliver, upstream protocol: webhook). Consumption runs in a group shared by the replicas, one replica per message, in the Standard Webhooks format: webhook-id equal to the event id, an HMAC-SHA256 signature covering the attributes, two active secrets for rotation, a structured CloudEvent as the body. A partner thus receives its tenant's events without access to the broker.

The address is checked at connection time: loopback, link-local and cloud metadata addresses are always refused, private ranges only with allow_private, with no proxy and no redirect. Retries are bounded (retries.max, retries.max_delay) and honour Retry-After, with a circuit breaker per target. The position advances only after a 2xx; once retries are exhausted or on a 4xx refusal, the intact event goes to the declared dead-letter queue with problemcode and problemstatus, from where it can be replayed.

A delivery has no caller: a channel bound to a caller fact (subject, claim) cannot be delivered by webhook, and a delivery without a tenant or without a dead-letter queue is refused at load.

All the points

  • Standard Webhooks, HMAC-SHA256, two-secret rotation
  • Address checked at connection, no redirect
  • At least once, dead-letter queue mandatory
  • Bounded retries, circuit breaker per target

Features and status

  • Signed, replayable outgoing webhooksDelivered · v1.5.0
Read in the documentation : Receiving signed webhooks

Native Kafka proxy

In part

The native Kafka proxy connects Kafka clients directly to the gateway, with virtual clusters and topics per tenant.

  • Native Kafka proxy: delivered · v1.6.1
  • ACLs and quotas per Kafka client: in part
  • Message field-level encryption: delivered · v1.6.1
See the detailHide the detail - Native Kafka proxy

The delivered asynchronous plane mediates between HTTP and brokers. The native Kafka proxy goes further: Kafka clients connecting directly to the gateway, with virtual clusters and topics per tenant.

It comes with ACLs and quotas per Kafka client, then field-level encryption of messages at the proxy. The state of these three features in this release, read from the product's catalogue, is shown below.

All the points

  • Native Kafka proxy: delivered · v1.6.1
  • ACLs and quotas per Kafka client: in part
  • Message field-level encryption: delivered · v1.6.1

Features and status

  • Native Kafka proxy: Kafka clients on the gateway, virtual clusters and topics per tenantDelivered · v1.6.1
  • ACLs and quotas per Kafka client at the native proxyIn part
  • Message field encryption at the native proxyDelivered · v1.6.1
Read in the documentation : Native Kafka clients: a virtual cluster per tenant

Configuration

No complete example for this domain in release v1.6.3 yet: one will come with an upcoming release.

Features

What is delivered in the published release v1.6.3, and what is coming; a feature is never shown as delivered before its release.

FeatureStatus
AsyncAPI as the source of the asynchronous planeDelivered · v1.5.0
Kafka publishing under contract, CloudEvents envelopeDelivered · v1.5.0
Mediation of the synchronous to asynchronous boundaryDelivered · v1.5.0
AMQP(S) and MQTTDelivered · v1.5.0
Signed, replayable outgoing webhooksDelivered · v1.5.0
Native Kafka proxy: Kafka clients on the gateway, virtual clusters and topics per tenantDelivered · v1.6.1
ACLs and quotas per Kafka client at the native proxyIn part
Message field encryption at the native proxyDelivered · v1.6.1
Console: Kafka clients and clusters, connections per tenant, refusals by cause, encryption and built-in alert rulesDelivered · v1.6.1

Every feature

The other expectations of this domain

  • Autonomous local orchestrationLocal decision by declared rules; orchestration stays with the decision servicePartly · next to be scheduled
  • Decisions tied to the real state of the systemexternal-call covers HTTP; asynchronous commands: candidateTo be scheduled
  • Normalise field protocols (MQTT, Sparkplug B, OPC UA PubSub)MQTT listener as a proxy, Sparkplug B, OPC UA PubSub JSONPlanned in 1.7
  • CoAP for constrained devicesNo CoAP listener; candidate on real demandTo be scheduled
  • Device identity, certificates, segmentationX.509, token, key per device, topic bound to the identityPlanned in 1.7

The other domains

Let's talk about your gateway

Flexwiz is a young company: you talk directly with the person who founds it. Tell us what you want to run through Flexway. We talk about your infrastructure and your digital sovereignty requirements.

Online booking is coming soon; until then, an e-mail is enough.