diff --git a/opencdc/data.go b/opencdc/data.go index 0fb5524..962fb0d 100644 --- a/opencdc/data.go +++ b/opencdc/data.go @@ -87,8 +87,8 @@ func (d RawData) Clone() Data { func (d RawData) MarshalJSON(ctx context.Context) ([]byte, error) { if ctx != nil { - s := ctx.Value(jsonSerializerCtxKey{}) - if s != nil && s.(*JSONSerializer).RawDataAsString { + s := ctx.Value(jsonMarshalOptionsCtxKey{}) + if s != nil && s.(*JSONMarshalOptions).RawDataAsString { // We should serialize RawData as a string. return json.Marshal(string(d)) } diff --git a/opencdc/json.go b/opencdc/json.go index 2935fe6..fd785f0 100644 --- a/opencdc/json.go +++ b/opencdc/json.go @@ -15,11 +15,30 @@ package opencdc import ( + "context" "fmt" "github.com/goccy/go-json" ) +// JSONMarshalOptions can customize how a record is serialized to JSON. It can +// be attached to a context using WithJSONMarshalOptions and supplied to +// json.MarshalContext to customize the serialization behavior. +type JSONMarshalOptions struct { + // RawDataAsString is a flag that indicates if the RawData type should be + // serialized as a string. If set to false, RawData will be serialized as a + // base64 encoded string. If set to true, RawData will be serialized as a + // string without conversion. + RawDataAsString bool +} + +type jsonMarshalOptionsCtxKey struct{} + +// WithJSONMarshalOptions attaches JSONMarshalOptions to a context. +func WithJSONMarshalOptions(ctx context.Context, options *JSONMarshalOptions) context.Context { + return context.WithValue(ctx, jsonMarshalOptionsCtxKey{}, options) +} + func (r *Record) UnmarshalJSON(b []byte) error { var raw struct { Position Position `json:"position"` diff --git a/opencdc/serializer.go b/opencdc/serializer.go index 6ea52d2..d2e4879 100644 --- a/opencdc/serializer.go +++ b/opencdc/serializer.go @@ -26,19 +26,12 @@ type RecordSerializer interface { Serialize(Record) ([]byte, error) } -// JSONSerializer is a RecordSerializer that serializes records to JSON. -type JSONSerializer struct { - // RawDataAsString is a flag that indicates if the RawData type should be - // serialized as a string. If set to false, RawData will be serialized as a - // base64 encoded string. If set to true, RawData will be serialized as a - // string without conversion. - RawDataAsString bool -} - -type jsonSerializerCtxKey struct{} +// JSONSerializer is a RecordSerializer that serializes records to JSON using +// the configured options. +type JSONSerializer JSONMarshalOptions func (s JSONSerializer) Serialize(r Record) ([]byte, error) { - ctx := context.WithValue(context.Background(), jsonSerializerCtxKey{}, &s) + ctx := WithJSONMarshalOptions(context.Background(), (*JSONMarshalOptions)(&s)) defer func() { // Workaround because of https://github.com/goccy/go-json/issues/499. // TODO: Remove this when the issue is fixed and store value in context