camelCase API フィールド用 serde(rename)

JavaScript 風の camelCase JSON キーを Rust の snake_case フィールドに #[serde(rename = ...)] や rename_all でマップします。

Patterns

詳細な説明

camelCase JSON と snake_case Rust を橋渡しする

ほとんどの JavaScript / Java バックエンドは camelCase の JSON キー(firstNamecreatedAt)を出力しますが、Rust のスタイルガイドは snake_case(first_namecreated_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 が必須になります。

試してみる — JSON to Rust Struct Converter

フルツールを開く