Files
warmbly/internal/infrastructure/codec/codec.go
T
Matthew Meszaros f106c8541d feat: make the bus envelopes Avro-encodable (#535)
* feat: make both bus envelopes Avro-encodable by deriving each one's schema from a declared registry of body types, with a union branch per body and our own struct walk that skips unexported fields and honours avro:"-" before descending, so the schema describes exactly what encoding/json already puts on the wire, and narrow the two sync cursors on the wire DTOs to int64 because Avro has no unsigned 64-bit type

* feat: stop the instance health check, the config registry and the docs all claiming Avro cannot serialize a worker envelope, which stopped being true once the envelopes carried a declared union, and check the one thing that is still a real misconfiguration instead: avro selected with no SCHEMA_REGISTRY_URL to resolve against

* feat: emit a reference the second time a record appears in an envelope schema instead of defining it again, because Avro names a record once and a document that defines warmbly.events.Token three times is rejected outright, and keep the Schema Registry round-trip as a skip-by-default test since only a registry judges the document rather than the objects it was built from

* feat: carry uint64 as Avro fixed(8) rather than long, which lets the sync cursors keep their unsigned type instead of being narrowed, name every event field after its json tag so the schema and the JSON wire agree, and populate every field in the round-trip test because zero values are why a uint64 mapped to long passed in the first place

* feat: frame Avro in Confluent's wire format and encode through hamba's default API instead of going through avrov2, whose private avro.API holds a type resolver avro.Register cannot reach, so a union body failed there with unable to resolve type while encoding cleanly against the same schema, and keep the registry round-trip as a skip-by-default test
2026-09-15 10:50:30 -07:00

43 lines
1.9 KiB
Go

// Package codec is the abstraction over event-payload serialization.
//
// Two implementations:
// - AvroCodec (Confluent Schema Registry wire format, encoded through
// hamba's default API so the envelopes' union bodies resolve)
// - JSONCodec (encoding/json — self-hostable alternative with no external
// schema registry dependency)
//
// The interface is intentionally small so the EventBus abstraction in
// internal/infrastructure/eventbus can stay transport-agnostic: the bus
// carries opaque bytes, the codec decides how those bytes are framed.
//
// Switching codecs requires that publishers and consumers agree: a JSONCodec
// consumer cannot decode an Avro-framed message and vice versa. There is no
// in-band marker, this is an operator-level configuration choice.
package codec
import "context"
// Codec serializes and deserializes event payloads. Implementations may
// require external services (Schema Registry for Avro) or be standalone
// (JSON). Implementations must be safe for concurrent use.
type Codec interface {
// Serialize encodes value into a transport-ready byte slice. topic is
// passed through because some codecs (Avro with subject naming strategy)
// need it to look up the right schema; codecs that don't care may ignore
// it.
Serialize(ctx context.Context, topic string, value any) ([]byte, error)
// Deserialize decodes payload into target, which must be a non-nil
// pointer to a value of the expected type. Same topic contract as
// Serialize.
Deserialize(ctx context.Context, topic string, payload []byte, target any) error
// Name returns a short identifier ("avro", "json") used in admin UI,
// startup logs, and audit trails.
Name() string
}
// Compile-time interface check. The AvroCodec check lives in avro.go (behind
// the `kafka` build tag) since that type isn't compiled into the default build.
var _ Codec = (*JSONCodec)(nil)