Skip to content

Kafka ​

A kafka binding is a typed connection to a Kafka topic — the durable, cross-instance sibling of an in-process topic. You produce with .send(v) from any handler; values cross the wire as JSON.

weld
type Order = { id: int, item: string }

kafka orders -> Order {
    brokers env("KAFKA_BROKERS")   # comma-separated host:port list
    topic   "orders"
}

route POST "/orders" (body o: Order) -> string {
    orders.send(o)                 # produce to Kafka
    respond "published"
}

Producing ​

name.send(v) JSON-encodes v (which must match the binding's message type) and produces one record to the topic. It speaks the Kafka wire protocol directly — no client library or sidecar — using a Produce request with a v2 record batch (CRC32C checked), so any Kafka-compatible broker (Apache Kafka, Redpanda) accepts it.

send is best-effort: broker/connection errors are logged, not thrown, so a Kafka blip never fails the request. For guaranteed delivery, produce from a worker that can retry.

Consuming ​

Consume a binding with for m in name inside a worker — the durable counterpart of consuming an in-process topic:

weld
worker {
    for o in orders {          # blocks for the next record; ends on shutdown
        ship(o)                # process it — write a DB row, call an upstream, …
    }
}

Each record's JSON is decoded into the binding's message type. Weld consumes with the message's committed group offset (or the earliest record for a new group), and commits progress as it goes — so a restart resumes where it left off (at-least-once). One worker per binding drains the topic; state touched in the loop is locked per message.

Configuration ​

FieldMeaning
brokerscomma-separated host:port bootstrap list (usually env(...))
topicthe Kafka topic name
groupconsumer group id for committed offsets; defaults to the binding name

Any of these can be an expression, so pull them from the environment per deploy.

Configuration ​

FieldMeaning
brokerscomma-separated host:port bootstrap list (usually env(...))
topicthe Kafka topic name
groupconsumer group id (for consuming; defaults to the binding name)

Any of these can be an expression, so pull them from the environment per deploy.

Scope ​

Weld speaks the Kafka wire protocol against the bootstrap broker — ideal for single-broker and dev/staging clusters (Apache Kafka, Redpanda). Producing sends to partition 0 with acks=1; consuming reads all partitions and commits offsets to the group. Still to come:

  • Multi-broker leader/coordinator routing (via Metadata/FindCoordinator) for large clusters.
  • Partitioning by key, producer batching/compression, and configurable acks.
  • Consumer groups with rebalancing (today one consumer instance owns the topic).