Serdeの読み方は?Rust serde入門と#[serde]属性の使い方
Rustのコードで頻出する「serde」。検索で最も多い疑問が読み方です。結論から言うと、serdeはSerialize(シリアライズ)とDeserialize(デシリアライズ)をつなげた造語で、読みは「サーディ」または「サード」。RustでJSONや設定ファイルを構造体と相互変換するときの事実上の標準ライブラリです。この記事では読み方と名前の由来から、cargo addでの導入、#[derive(Serialize, Deserialize)]、実務でつまずきやすいrename_all・default・skip_serializing_ifといった属性、serde_jsonの使い方までをコード付きで整理します。serde_yamlの非推奨化など2026年時点の注意点も押さえます。
まとめ
- 読み方:serde=Serialize+Deserializeの造語。「サーディ/サード」と読まれる(公式に確定した発音はない)。
- 導入:
cargo add serde --features deriveとcargo add serde_jsonの2つが基本セット。 - 基本:構造体に
#[derive(Serialize, Deserialize)]を付けるだけで、serde_json::to_string/from_strが使える。 - 属性:フィールド名変換は
rename_all、欠損時の既定値はdefault、出力の省略はskip_serializing_if。 - 注意:YAML用の serde_yaml は2024年にアーカイブ(非推奨)。TOMLは
serde_tomlではなくtomlクレートを使う。
Serdeの読み方と名前の由来
serdeは serialize と deserialize の頭を取った造語です。作者(dtolnay 氏)が公式に「この発音が正しい」と定めているわけではなく、コミュニティでは主に次のように読まれます。
- サーディ(ser-dee)… 「サーディー」と伸ばす読み方。英語圏でよく使われる。
- サード(serd)… 1音節でフランス語の「merde」に韻を踏ませる読み方。
どちらでも通じます。由来がSerialize+Deserializeだと分かっていれば、綴りも役割も迷いません。以降、この「シリアライズ(Rustの値→JSONなどの文字列)」「デシリアライズ(文字列→Rustの値)」という2方向の変換がserdeの中心概念になります。
Serdeの役割:Rustのシリアライズ標準フレームワーク
serdeは、Rustのデータ構造とJSON・TOML・YAML・MessagePackなどの外部フォーマットを相互変換するためのフレームワークです。特徴は、変換ロジックをコンパイル時にderiveマクロで自動生成する点にあります。実行時にリフレクションで型を調べる言語と違い、型ごとに専用の変換コードが生成されるため、型安全性と速度を両立できます。
serde本体(serde クレート)が担うのは Serialize / Deserialize という2つのトレイトの定義とderiveマクロだけで、実際のフォーマット処理は serde_json や toml といったデータフォーマットごとの別クレートが担当します。この分離により、同じ構造体定義のままフォーマットを差し替えられます。
Serdeの導入:cargo addとfeatures
JSONを扱う最小構成は次の2行です。--features derive を付けないと #[derive(Serialize, Deserialize)] が使えないので注意してください。
cargo add serde --features derive
cargo add serde_json
Cargo.tomlに直接書く場合は次の形になります。
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
Cargoやプロジェクト構成そのものに不安があれば、Cargo(Rust)の使い方・主要コマンドの解説もあわせて確認すると導入でつまずきにくくなります。
SerializeとDeserializeをderiveで実装する
serdeの基本は、変換したい構造体に #[derive(Serialize, Deserialize)] を付けることです。あとは serde_json::to_string(Rust→JSON)と serde_json::from_str(JSON→Rust)を呼ぶだけで双方向の変換ができます。
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct User {
name: String,
age: u8,
}
fn main() {
let u = User { name: "Sato".to_string(), age: 30 };
// シリアライズ: User → JSON文字列
let json = serde_json::to_string(&u).unwrap();
println!("{json}"); // {"name":"Sato","age":30}
// デシリアライズ: JSON文字列 → User
let back: User = serde_json::from_str(&json).unwrap();
println!("{}", back.age); // 30
}
Serialize だけ、Deserialize だけを付けることもできます。APIのレスポンス専用の型なら Serialize のみ、設定ファイル読み込み専用なら Deserialize のみ、と役割で絞ると無駄なコード生成を避けられます。enumやネストした構造体も、内部の型がすべてこれらのトレイトを実装していれば同じようにderiveできます。
#[serde(…)]属性の実務リファレンス
実務でserdeを使うと、必ず「JSONのキー名がRustの命名規則と合わない」「フィールドが欠けているJSONを読みたい」「nullは出力したくない」といった要求が出てきます。これらは #[serde(...)] 属性で解決します。使用頻度の高い3つを用途別に整理します。
フィールド名を変換する:renameとrename_all
Rustは snake_case、JSON APIは camelCase が多く、命名が食い違います。構造体全体に rename_all を付ければ、フィールドを個別に書き換えずに一括変換できます。
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Profile {
user_name: String, // JSONでは "userName"
created_at: String, // JSONでは "createdAt"
}
rename_all に指定できる主な値は "camelCase" "snake_case" "PascalCase" "SCREAMING_SNAKE_CASE" "kebab-case" です。特定の1フィールドだけ名前を変えたいときは、そのフィールドに #[serde(rename = "id")] のように個別指定します。個別の rename は rename_all より優先されます。
欠損フィールドを補う:default
キーが存在しないJSONをデシリアライズすると、通常はエラーになります。#[serde(default)] を付けると、欠損時に型の既定値(数値は0、bool は false、String は空文字)が使われます。任意項目を持つ設定ファイルの読み込みで多用します。
#[derive(Deserialize)]
struct Settings {
#[serde(default)]
retries: u32, // 欠損時は 0
#[serde(default = "default_port")]
port: u16, // 欠損時は default_port() が呼ばれる
}
fn default_port() -> u16 { 8080 }
0やfalseではなく特定の初期値にしたい場合は、上のように default = "関数名" で既定値を返す関数を指定します。
出力を省く:skip_serializing_ifとskip
Option がNoneのときにキーごと出力から消したい、というのはAPIレスポンスで頻出です。#[serde(skip_serializing_if = "Option::is_none")] を使うと、条件を満たすフィールドはシリアライズ時に出力されません。
#[derive(Serialize)]
struct ApiResponse {
id: u32,
#[serde(skip_serializing_if = "Option::is_none")]
note: Option<String>, // None なら JSON に出さない
}
入出力の両方向で常に無視したいフィールド(内部計算用の一時値など)には #[serde(skip)] を使います。この場合そのフィールドは Default トレイトの既定値で埋められるため、対象の型が Default を実装している必要があります。
serde_jsonでJSONを読み書きする
JSONの実処理は serde_json が担います。よく使う関数は、文字列との相互変換 to_string / from_str、整形出力の to_string_pretty、そしてストリームへ直接書き出す to_writer です。デバッグ時は to_string_pretty で改行・インデント付きにすると差分が読みやすくなります。
let pretty = serde_json::to_string_pretty(&u).unwrap();
println!("{pretty}");
構造が事前に決まらない可変のJSONは、専用の構造体を定義せず serde_json::Value で受け取れます。Value はオブジェクト・配列・数値などを表す列挙型で、キーやインデックスでたどれます。
let v: serde_json::Value = serde_json::from_str(r#"{"a": 1}"#).unwrap();
println!("{}", v["a"]); // 1
JSONそのものの型(オブジェクト・配列・数値・文字列など)を整理しておきたい場合は、JSONの型定義とデータ型一覧が土台の理解に役立ちます。RustのWeb APIでリクエストボディをJSONで受けるなら、Rust製WebフレームワークAxumの使い方がserdeとの組み合わせの実例になります。
JSON以外のフォーマットとクレート選定の注意(TOML・YAML)
serdeはJSON専用ではありません。同じderive済み構造体を、フォーマット別のクレートに渡すだけで扱えます。ここは古い記事や古いプロジェクトの設定が残りやすく、事実として間違いやすい箇所なので明確にしておきます。
| フォーマット | 使うクレート | 2026年時点の状況 |
|---|---|---|
| JSON | serde_json | 現役・標準。まずこれ。 |
| TOML | toml | 現役。serde_tomlではない。 |
| YAML | (要検討) | serde_yamlは非推奨。代替を選ぶ。 |
| バイナリ | bincode / MessagePack系 | 速度・サイズ重視の用途。 |
TOMLでよくある誤解が、serde_toml というクレート名です。実在するのは toml クレートで、toml::from_str / toml::to_string がserdeの構造体をそのまま受け付けます(cargo add toml で追加)。serde_toml を探しても目的の機能は見つからないので、toml を使ってください。
YAMLは注意が必要です。長らく定番だった serde_yaml は2024年3月に作者がリポジトリをアーカイブし、メンテナンス終了(非推奨)となりました。新規プロジェクトで安易に serde_yaml を追加するのは避け、後継・代替クレート(例:serde_norway など)を用途と保守状況を確認したうえで選ぶべきです。設定ファイルの形式に強いこだわりがなければ、保守が活発なJSONやTOMLに寄せるのが最も安全な判断です。変動が早い領域なので、採用前に各クレートの最新のメンテナンス状況を公式で確認してください。
よくある質問
serdeの読み方は何ですか?
serialize+deserializeの造語で、「サーディ(ser-dee)」または「サード(serd)」と読まれます。公式に確定した発音はなく、どちらでも通じます。
serdeとserde_jsonの違いは何ですか?
serdeは変換の仕組み(Serialize / Deserializeトレイトとderiveマクロ)を提供する本体で、serde_jsonはそれをJSONという具体的なフォーマットに適用する実装クレートです。JSONを扱うには両方が必要です。
serde(default)を付けると欠損フィールドはどうなりますか?
キーが無いJSONでもエラーにならず、型の既定値(数値0・bool false・String空文字)が入ります。特定の初期値にしたいときは default = "関数名" で既定値を返す関数を指定します。
rename_allでcamelCaseに変換するには?
構造体に #[serde(rename_all = "camelCase")] を付けます。user_name が userName のように一括変換され、個別フィールドを書き換える必要がありません。
serde_yamlはまだ使えますか?
2024年3月にアーカイブされ非推奨です。既存コードで動いてはいますが、新規採用は避け、後継クレートやJSON/TOMLへの移行を検討してください。