Payload Codec
Serialization seam for saga payloads stored in a SagaJournal.
This is the only serialization boundary in the journal SPI. The executor and SagaJournal implementations treat payload bytes as opaque; users bring their own codec (kotlinx-serialization, Jackson, Protobuf, …) without pulling any serialization library into kstate-saga itself.
Codec placement rule (D3): PayloadCodec<P> is adapter-internal.
Persistent adapters (Room, JDBC, file, …) accept the codec in their own constructor and call
encode/decodeat persistence boundaries.InMemorySagaJournal<P>storesPdirectly and never calls this codec.The executor never calls
encodeon the hot path.
Usage example
val orderCodec = object : PayloadCodec<OrderEvent> {
override fun encode(payload: OrderEvent): ByteArray = Json.encodeToString(payload).encodeToByteArray()
override fun decode(bytes: ByteArray): OrderEvent = Json.decodeFromString(bytes.decodeToString())
}
val journal = RoomSagaJournal(db, codec = orderCodec)DSL registry (conversational DSL — F006)
To use keep audit in journal inside a saga builder block, the codec for the payload type must be registered once at application startup:
// At startup:
PayloadCodec.register<OrderEvent>(orderCodec)
// Inside the saga builder:
sagaExecutor<OrderCtx, OrderResult> {
keep.audit `in` roomJournal // T = OrderEvent inferred from journal type
first call "reserve" with { ... }
}If no codec is registered for the journal's payload type, the DSL fails immediately with an IllegalStateException that names the missing type and points at both recovery paths (register here, or use the typed factory).
Parameters
The payload type this codec handles.