serde Best Practices
Rules for stable, versioned, forward-compatible serialization schemas in production Rust services.
Busca en todas las páginas de la documentación
Rules for stable, versioned, forward-compatible serialization schemas in production Rust services.
untagged for external APIs.#[serde(default)] on new optional fields. Old clients can omit them.version field to persisted blobs. Migrate readers explicitly.Option skips vs explicit null affects clients.alias for renames during transition.deny_unknown_fields on inbound untrusted data. Reject surprise keys.#[serde(other)] variant for unknown event types. Forward-compatible consumers.&str only when buffer outlives value. Default to String in handlers.serde_json::Value for hot paths. Typed structs or streaming.unwrap parse results on untrusted input. Map to typed errors.cargo fuzz on decode entry points. Find panics before attackers do.Breaking wire compatibility without version field or consumer upgrade path.
Acceptable at API boundaries - cheaper than breaking mobile clients.
rename_all = "camelCase" on all external JSON DTOs - consistent once chosen.
Only if Rust-only readers; version prefix mandatory.
#[serde(skip_serializing)] on secrets; never deserialize inbound secrets from clients.
RFC 3339 strings via serde_with or custom with module - document timezone.
String-encode u64 IDs in JSON for JavaScript interop if needed.
Internally tagged enum array - snapshot each variant.
TOML for human edit; strict deny_unknown_fields on load.
Round-trip + unknown field rejection + one legacy payload fixture.
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Revisado por Chris St. John·Última actualización: 16 jul 2026