serde
serde is the serialization framework most Rust services build on. It separates data shape (your types) from wire format (JSON, MessagePack, TOML, and more) through Serialize and Deserialize traits.
Busca en todas las páginas de la documentación
serde is the serialization framework most Rust services build on. It separates data shape (your types) from wire format (JSON, MessagePack, TOML, and more) through Serialize and Deserialize traits.
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct User {
id: u64,
email: String,
}
fn main() -> serde_json::Result<()> {
let u = User { id: 1, email: "ada@acme.com".into() };
let json = serde_json::to_string(&u)?;
let back: User = serde_json::from_str(&json)?;
assert_eq!(back.email, "ada@acme.com");
Ok(())
}When to reach for this:
sqlx or sea-orm)use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Event {
#[serde(rename = "event_type")]
kind: String,
#[serde(default)]
retries: u32,
}
// Accepts {"event_type":"created"} without retries field
let e: Event = serde_json::from_str(r#"{"event_type":"created"}"#).unwrap();What this demonstrates:
Serialize writes a type; Deserialize reconstructs it.serde_json, serde_yaml, toml, bincode are separate crates.#[derive(Serialize, Deserialize)] generates impls at compile time.#[serde(with = "module")] or manual impls for odd formats.For exhaustive coverage, see the dedicated serde basics section: custom serializers, enum tagging, and zero-copy patterns.
#[serde(tag = "type")] for APIs.serde_json::Value everywhere. Fix: typed structs at boundaries.deny_unknown_fields on public APIs - clients send typos silently. Fix: enable on request types.Cargo.toml.| Alternative | Use When | Don't Use When |
|---|---|---|
miniserde | Minimal binary size | You need full derive ergonomics |
Manual Display | Tiny fixed formats | Evolving schemas |
protobuf / capnp | gRPC, strict schemas | Quick internal JSON APIs |
No. Add only the format crates you use. serde alone has no format.
Yes with #[serde(borrow)] and Deserialize<'de> when lifetimes are explicit. Owned types are simpler for APIs.
Use #[serde(skip_serializing_if = "Option::is_none")] on Option fields.
Derive-generated code is fast. Bottlenecks are usually IO and allocation, not serde itself.
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