Rust's Serde: Taming JSON with Types
Serde JSON translates between human-readable JSON text and native Rust structs, acting as a bilingual interpreter for your data. Use it for web APIs or config files.
Why it exists
Applications need to communicate using standard formats like JSON, which is just text. Rust, with its strong type system, needs a safe and efficient way to convert this text into its own data structures to work with it, and then convert it back to text to send out. Serde provides this robust translation layer.
The mental model
Think of Serde as a contract enforcer for your data. You define a Rust struct that represents the "contract" for the JSON you expect. When JSON arrives, Serde tries to fit the data into your struct. If it matches, you get a native Rust type you can work with safely. If it doesn't, you get a clear, compile-time or runtime error, preventing bad data from corrupting your program.
How it works
Serde JSON offers two primary modes. First, for strongly-typed data, you add #[derive(Serialize, Deserialize)] to a Rust struct. Serialize converts the struct into a JSON string. Deserialize parses a JSON string into an instance of the struct. Second, for untyped or unknown data, you can parse JSON into a serde_json::Value enum. This generic structure holds any valid JSON, which you can then inspect dynamically using index access like my_value["key"].
When to use it
Use the strongly-typed approach (structs with derive) whenever you know the structure of the JSON data, like for your application's API endpoints or configuration files. This is the most common and safest use case. Use the untyped Value enum when you need to handle arbitrary JSON, inspect a small part of a large document, or modify JSON without knowing its full structure.
When not to use it
Avoid the untyped Value approach for data with a known, stable structure. Relying on string keys for access (e.g., v["nmae"]) is fragile because a simple typo becomes a runtime logic error that silently returns a null value, not a compile-time error. For hyper-performance-critical paths where JSON parsing is too slow, consider binary formats like Protocol Buffers or MessagePack, which Serde also supports.
One canonical example
To parse JSON into a type-safe struct, first define the struct and derive Deserialize. For a struct Person { name: String, age: u8 }, you would add #[derive(Deserialize)] above it. Then, given a JSON string like let data = r#"{ "name": "John Doe", "age": 43 }"#;, you can parse it with let p: Person = serde_json::from_str(data).unwrap();. This gives you a native Person instance, and you can access its fields directly, like p.name.
Interview question
When is it most appropriate to use `serde_json::Value` for parsing JSON in Rust, rather than a custom struct with `#[derive(Deserialize)]`?
- a.When parsing performance is the absolute highest priority for known, stable JSON structures.
- b.When you need to ensure compile-time type safety for every field in the JSON.
- c.When the JSON structure is dynamic, partially unknown, or you only need to access a few fields without defining the whole schema.Correct
- d.When the JSON data originates from a highly trusted, internal service.
Why? this is the answer
The card states that `serde_json::Value` is for "untyped or unknown data" or when you need to "inspect a small part of a large document" without knowing its full structure. Conversely, `#[derive(Deserialize)]` provides compile-time type safety for known, stable structures, making option B incorrect.
Just read this? Test yourself on what you have been reading.
Read the original → docs.rs
- #rust
- #serde
- #json
- #serialization
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on rust — each one lists the topics its interview covers.
See open roles