Extended serialization

Serde.jl lets you customise how your types are serialized by overriding a small set of trait functions. All traits are dispatched on the concrete type being serialized, optionally combined with a strategy object.

Renaming output fields

Serde.ser_nameFunction
Serde.ser_name(::Type{T}, ::Val{field}) -> Symbol
Serde.ser_name(strategy, ::Type{T}, ::Val{field}) -> Symbol

Returns the output key name for field of type T during serialization.

Override to rename individual fields in the serialized output. The default returns field unchanged. Context objects such as CamelCase provide global renaming policies by overriding the context-aware variant.

Examples

struct User
    user_name::String
end

# Output as "userName" in JSON/YAML/etc.
Serde.ser_name(::Type{User}, ::Val{:user_name}) = :userName

See also: Serde.deser_name, CamelCase.

source

Transforming field values

Serde.ser_valueFunction
Serde.ser_value(::Type{T}, ::Val{field}, value)
Serde.ser_value(strategy, ::Type{T}, ::Val{field}, value)

Transforms the value of field in a value of type T before serialization.

Applied per-field, before Serde.ser_type. Use this hook to convert domain values to serialization-friendly forms (e.g. DateTime to Unix timestamp, Enum to string code).

Examples

struct Event
    timestamp::Int64  # stored as Unix ms
end

# Store the underlying DateTime as milliseconds since epoch
Serde.ser_value(::Type{Event}, ::Val{:timestamp}, v::DateTime) =
    Dates.value(v - DateTime(1970))

See also: Serde.ser_type, Serde.ser_skip.

source

Transforming values by type

Serde.ser_typeFunction
Serde.ser_type(::Type{T}, value)
Serde.ser_type(strategy, ::Type{T}, value)

Type-level value transformation applied during serialization after Serde.ser_value.

Unlike ser_value, this hook is not per-field: it is dispatched on the type T being serialized and the resulting value. Use it for uniform post-processing (e.g. rounding all floats in a struct).

See also: Serde.ser_value.

source

Skipping fields

Serde.ser_skipMethod
Serde.ser_skip(::Type{T}, ::Val{field}) -> Bool
Serde.ser_skip(strategy, ::Type{T}, ::Val{field}) -> Bool

Returns true to unconditionally omit field of type T from serialized output.

Use to exclude internal or sensitive fields regardless of their value. The default returns false (include all fields).

Examples

struct User
    name::String
    password_hash::String  # never serialize this
end

Serde.ser_skip(::Type{User}, ::Val{:password_hash}) = true

See also: Serde.ser_skip(::Type, ::Val, ::Any).

source
Serde.ser_skipMethod
Serde.ser_skip(::Type{T}, ::Val{field}, value) -> Bool
Serde.ser_skip(strategy, ::Type{T}, ::Val{field}, value) -> Bool

Returns true to omit field of type T when it holds the given value.

Use to implement "skip if null", "skip if zero", or any value-conditional omission. Falls back to ser_skip(T, Val(field)) (the value-independent variant) by default.

Examples

struct Response
    data::Union{Nothing,String}
    error::Union{Nothing,String}
end

# Omit fields that are nothing
Serde.ser_skip(::Type{Response}, ::Val{:data}, v) = isnothing(v)
Serde.ser_skip(::Type{Response}, ::Val{:error}, v) = isnothing(v)

See also: Serde.ser_skip(::Type, ::Val), Serde.isnull.

source