---
title: "Serdeの読み方は？Rust serde入門と#[serde]属性の使い方"
url: "https://www.issoh.co.jp/tech/details/5551/"
published: 2025-02-26
updated: 2026-09-27
categories: ["Rust"]
publisher: "株式会社一創"
---

# Serdeの読み方は？Rust serde入門と\#\[serde\]属性の使い方

Rustのコードで頻出する「serde」。検索で最も多い疑問が**読み方**です。結論から言うと、serdeは**Ser**ialize（シリアライズ）と**De**serialize（デシリアライズ）をつなげた造語で、読みは「サーディ」または「サード」。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は **ser**ialize と **de**serialize の頭を取った造語です。作者（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）の使い方・主要コマンドの解説](https://www.issoh.co.jp/tech/details/9572/)もあわせて確認すると導入でつまずきにくくなります。

## 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の型定義とデータ型一覧](https://www.issoh.co.jp/tech/details/2682/)が土台の理解に役立ちます。RustのWeb APIでリクエストボディをJSONで受けるなら、[Rust製WebフレームワークAxumの使い方](https://www.issoh.co.jp/tech/details/7602/)が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への移行を検討してください。

## 関連記事

- [Cargo（Rust）とは？インストールから使い方・主要コマンドまで完全ガイド](https://www.issoh.co.jp/tech/details/9572/)
- [Axumとは？Rust製Webフレームワークの特徴・使い方・Actix Web/Rocket比較を解説](https://www.issoh.co.jp/tech/details/7602/)
- [JSONの型定義とデータ型一覧｜6つの型とTypeScriptで型安全に扱う方法](https://www.issoh.co.jp/tech/details/2682/)

---

出典: [Serdeの読み方は？Rust serde入門と\#\[serde\]属性の使い方](<https://www.issoh.co.jp/tech/details/5551/>)（株式会社一創）
