Skip to content

Why the specification and not the SDK

There is an official CloudEvents SDK for Go, it is well made, and this module does not use it.

What the SDK costs

github.com/cloudevents/sdk-go/v2 requires go.uber.org/zap, json-iterator, go-cmp, bytebufferpool, two golang.org/x packages and four further indirect dependencies.

This estate is slog everywhere, and has recently been through the work of removing a logging-adjacent dependency across the toolkit. Taking a second structured logger into the graph of every service that sends a message is a poor trade for an envelope.

What the specification costs

Eight attributes, one prefix, one special case for content-type, and a naming rule for extensions. The codec, the event type, the encoding rules and the error sentinels come to about 760 lines including the doc comments. The whole module, URN grammar and all, is under 1,200.

The part that is not free

We own conformance. Nobody else's test suite tells us we got the format right, so the tests carry that weight instead:

  • Fixtures written by hand from the specification, so a change in our reading of it fails.
  • A fixture produced by the SDK itself, checked in at testdata/sdk-binary-1.0.txt, so a drift from what the rest of the world writes fails.

That second one is the important one. A round trip through our own Marshal and Unmarshal proves only that the two agree with each other; it would pass happily if every header were renamed consistently. Interoperability is the entire reason to implement a standard rather than invent one, so it gets a test that can actually fail.

The SDK is a fixture generator, not a dependency, and testdata/README.md records how to regenerate it.

And what we do not get

Structured mode, and the protocol bindings. Both matter less once the bindings have been ruled out for owning the connection.