camelCase API フィールド用 serde(rename)
JavaScript 風の camelCase JSON キーを Rust の snake_case フィールドに #[serde(rename = ...)] や rename_all でマップします。
詳細な説明
camelCase JSON と snake_case Rust を橋渡しする
ほとんどの JavaScript / Java バックエンドは camelCase の JSON キー(firstName、createdAt)を出力しますが、Rust のスタイルガイドは snake_case(first_name、created_at)を要求します。serde はこの両方を成立させてくれます。
JSONの例
{
"firstName": "Ada",
"lastName": "Lovelace",
"createdAt": "2024-01-15T10:00:00Z"
}
フィールド単位のリネーム(自動生成)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Root {
#[serde(rename = "firstName")]
pub first_name: String,
#[serde(rename = "lastName")]
pub last_name: String,
#[serde(rename = "createdAt")]
pub created_at: String,
}
コンテナレベルのリネーム
すべてのフィールドが同じ命名規則に従っているなら、フィールド単位の属性を置き換えてコンテナレベルの rename_all を使う方が短くて忘れにくく、出力もまったく同じになります。
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Root {
pub first_name: String,
pub last_name: String,
pub created_at: String,
}
利用可能な rename_all の値
"lowercase"、"UPPERCASE"、"PascalCase"、"camelCase"、"snake_case"、"SCREAMING_SNAKE_CASE"、"kebab-case"、"SCREAMING-KEBAB-CASE"。
命名規則が混在する場合
例外フィールドが少数なら、コンテナレベルの rename_all とフィールド単位の rename を組み合わせます。
#[serde(rename_all = "camelCase")]
pub struct Root {
pub first_name: String,
pub last_name: String,
#[serde(rename = "URL")]
pub url: String,
}
リネームが重要な理由
これらの属性なしでは、デシリアライズが missing field "first_name" で失敗します。JSON キーは firstName なのに、serde は完全一致を探すからです。リネーム属性で、Rust 側のクリーンな API を保ちつつ、上流が出してくる任意の wire 形式と互換性を確保できます。
ユースケース
TypeScript / Java / Kotlin ベースのバックエンドのほぼすべてが camelCase の JSON を出力します。それらを消費する Rust クライアントは、idiomatic な snake_case フィールドを保ちつつ wire 契約を壊さないために rename_all が必須になります。