ADR 0023: CloudEvents Handlers¶
Status: Proposed Date: 2026-05-24
Context¶
Serverless and FaaS platforms — Knative, Google Cloud Run functions (Functions
Framework), Azure Event Grid and Functions — deliver events as CNCF
CloudEvents: a vendor-neutral envelope (id, source,
specversion, type, and optional subject, time, datacontenttype,
dataschema, data) defined over multiple transports. A "cloudevent function" simply
receives a CloudEvent and acts on it. The toolbox should let a Spikard service consume
CloudEvents and generate light, FaaS-style handlers, reusing the HTTP runtime and the
messaging subsystem rather than a bespoke path. CloudEvents publishes an official
JSON Schema (cloudevents/formats/cloudevents.json, spec v1.0.2), so the
implementation should validate against that schema and prove conformance with fixtures,
matching Spikard's existing schema-validation model (ADR 0003).
Decision¶
- A
spikard-cloudeventscrate provides the codec and atype-keyed dispatcher, built on the officialcloudevents-sdkcrate (Core v1.0, JSON event format, binary and structured content modes). Per ADR 0014, theCloudEventDTO lives inspikard-core::services; the codec, dispatcher, and handler trait arealef(skip)'d. - Validate against the official schema. Vendor
cloudevents/formats/cloudevents.json(v1.0.2) into the repo and validate decoded events with Spikard's existingjsonschemaengine — the same engine that validates HTTP inputs (ADR 0003). Binary mode (attributes in transport headers) maps to the same attribute model and is validated identically; structured mode validates the JSON envelope directly. - A
CloudEventHandlertrait mirrors the other callback traits (ADR 0015): host code receives aCloudEventand is dispatched by eventtype(optionallysource) — the Functions-Framework "cloudevent function" signature. No new FFI mechanism. - Transport-agnostic. The codec rides over the HTTP runtime (CloudEvents HTTP
binding — binary vs structured distinguished by the
application/cloudeventsContent-Type prefix) and over the messaging subsystem (ADR 0017) using the matching CloudEvents protocol binding for each broker. One handler, either transport. The codec stays binding-agnostic so it composes with Spikard's pure-Rust messaging adapters rather than pulling thecloudevents-sdkrdkafka binding (which links librdkafka). - FaaS compatibility. The HTTP endpoint speaks the CloudEvents HTTP binding so a
Spikard service deploys as a Knative / Cloud Run function or an Azure Event Grid
subscriber, including the Event Grid abuse-protection handshake (an
OPTIONSrequest withWebHook-Request-Originanswered byWebHook-Allowed-Origin). - Light handler generation. The
spikard-clicode-generation pipeline (ADR 0004) generates thin per-event-type handler scaffolds from a declared event catalog (or AsyncAPI channels carrying CloudEvents): decode, dispatch bytype, call the host function — nothing heavier.
Consequences¶
- Reuses the consumer model (ADR 0015) and the HTTP handler path;
CloudEventis the only new binding-facing type. - The HTTP binding can land before the broker binding (it does not depend on messaging); the unified two-transport story depends on ADR 0017. CloudEvents is therefore sequenced with messaging in the roadmap.
- Conformance is fixture-driven (ADR 0022): fixtures derived from the spec exercise binary/structured HTTP decode, JSON-format round-trips, and required-attribute validation against the vendored schema — and every binding must agree. Real-platform conformance (Event Grid handshake, Knative delivery) is covered by Rust integration tests.
- The vendored schema is pinned to a spec version; bumping CloudEvents versions is a deliberate, reviewed update with regenerated conformance fixtures.
References¶
- Related: ADR 0003, ADR 0004, ADR 0014, ADR 0015, ADR 0017, ADR 0022
- Spec: CloudEvents v1.0.2, JSON Schema
cloudevents/formats/cloudevents.json, HTTP and Kafka bindings - External: cloudevents-sdk (Rust), GCP Functions Framework contract