zoobzio December 26, 2025 Edit this page

Providers

Five codec providers are included, each in its own submodule.

JSON

import "github.com/zoobzio/cereal/json"

codec := json.New()
PropertyValue
Content-Typeapplication/json
Human readableYes
Binary supportBase64 encoding
Struct tagjson

Standard library encoding/json under the hood.

XML

import "github.com/zoobzio/cereal/xml"

codec := xml.New()
PropertyValue
Content-Typeapplication/xml
Human readableYes
Binary supportBase64 encoding
Struct tagxml

Standard library encoding/xml under the hood.

Note: XML uses different struct tags than JSON:

// For JSON
type User struct {
    ID string `json:"id"`
}

// For XML
type User struct {
    ID string `xml:"id"`
}

// For both
type User struct {
    ID string `json:"id" xml:"id"`
}

YAML

import "github.com/zoobzio/cereal/yaml"

codec := yaml.New()
PropertyValue
Content-Typeapplication/yaml
Human readableYes
Binary supportBase64 encoding
Struct tagyaml

Uses gopkg.in/yaml.v3.

MessagePack

import "github.com/zoobzio/cereal/msgpack"

codec := msgpack.New()
PropertyValue
Content-Typeapplication/msgpack
Human readableNo
Binary supportNative
Struct tagmsgpack or json

Uses github.com/vmihailenco/msgpack/v5. Falls back to json tags if msgpack tags are not present.

BSON

import "github.com/zoobzio/cereal/bson"

codec := bson.New()
PropertyValue
Content-Typeapplication/bson
Human readableNo
Binary supportNative
Struct tagbson or json

Uses go.mongodb.org/mongo-driver/bson. Ideal for MongoDB integration.

Choosing a Provider

Use CaseRecommended
REST APIsJSON
Configuration filesYAML
Document interchangeXML
High-performance RPCMessagePack
MongoDB integrationBSON
DebuggingJSON or YAML

Provider Independence

The same type works with any provider:

type User struct {
    ID    string `json:"id" yaml:"id" xml:"id" msgpack:"id" bson:"id"`
    Email string `json:"email" yaml:"email" xml:"email" send.mask:"email"`
}

func (u User) Clone() User { return u }

jsonProc, _ := cereal.NewProcessor[User]()
jsonProc.SetCodec(json.New())
yamlProc, _ := cereal.NewProcessor[User]()
yamlProc.SetCodec(yaml.New())
bsonProc, _ := cereal.NewProcessor[User]()
bsonProc.SetCodec(bson.New())

// Same transforms, different wire format

Boundary tags (store.encrypt, send.mask, etc.) are provider-agnostic.

Submodule Installation

Each provider is a separate Go module for dependency isolation:

# Install only what you need
go get github.com/zoobzio/cereal/json
go get github.com/zoobzio/cereal/yaml
go get github.com/zoobzio/cereal/xml
go get github.com/zoobzio/cereal/msgpack
go get github.com/zoobzio/cereal/bson

This avoids pulling in dependencies you don't use (e.g., MongoDB driver for BSON).

Custom Providers

Implement the Codec interface:

type Codec interface {
    ContentType() string
    Marshal(v any) ([]byte, error)
    Unmarshal(data []byte, v any) error
}

Example for a hypothetical TOML provider:

package toml

import (
    "github.com/zoobzio/cereal"
    "github.com/pelletier/go-toml/v2"
)

type tomlCodec struct{}

func New() cereal.Codec { return &tomlCodec{} }

func (c *tomlCodec) ContentType() string { return "application/toml" }

func (c *tomlCodec) Marshal(v any) ([]byte, error) {
    return toml.Marshal(v)
}

func (c *tomlCodec) Unmarshal(data []byte, v any) error {
    return toml.Unmarshal(data, v)
}

Then use it:

proc, _ := cereal.NewProcessor[Config]()
proc.SetCodec(toml.New())

Content-Type Access

Get the underlying codec's content type:

proc, _ := cereal.NewProcessor[User]()
proc.SetCodec(json.New())
fmt.Println(proc.ContentType()) // "application/json"

Useful for setting HTTP headers:

func handler(w http.ResponseWriter, r *http.Request) {
    data, _ := proc.Encode(ctx, &user)
    w.Header().Set("Content-Type", proc.ContentType())
    w.Write(data)
}