0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Rust] DynamoDBテーブルのStringフィールドに入ったJSONをRustにてネストしたStructにDeserializeする

0
Last updated at Posted at 2026-06-23

はじめ

DynamoDBにて、JSON文字列をそのままString型で格納するケースで(設計の是非はさておき)、serde_dynamoではString型のフィールドにJSONが入っている場合、そのままではネストしたStructへのDeserializeができないなーと思いました
LLMは自分でDeserializerを作れやと言ってきましたが、作りたくありませんでした

前提

DynamoDBのデータ構造

以下のようなアイテムを想定

{
  "id": { "S": "hoge1234" },
  "name": { "S": "huga" },
  "details": { "S": "{\"key\":\"hoge\",\"description\":\"hogeeeeeeee\"}" }
}

details フィールドはDynamo上ではStringだが、中にはJSONがぶち込まれている

作りたいRustのStruct

#[derive(Debug, Deserialize)]
pub struct Hoge {
    pub id: String,
    pub name: String,
    pub details: HogeDetails,  // ここをいいかんじにしたい
}

#[derive(Debug, Deserialize)]
pub struct HogeDetails {
    pub key: String,
    pub description: String,
}

serde_dynamoだけでは動かない

※Dynamoから取得する部分のソースなどはネットの海に腐るほどあるので省略

Error: ErrorImpl { code: Message("invalid type: string \"...\", expected a map"), ... }

serde_dynamodetails フィールドを AttributeValue::S として受け取る
しかしRust側は HogeDetails Struct(Map)を期待している。String をそのままMapにキャストしようとしてエラー

serde_dynamo はDynamoの型システム(AttributeValue)を意識したものであり、Stringの中にさらに別のシリアライズ形式があることはさすがに解釈してくれない

serde_withのJsonStringを使えばいけた

serde_withが提供する JsonStringを使う
文字列として受け取った値を、さらにJSONとしてDeserializeするようにすればいいらしい

依存関係を追加

# Cargo.toml
[dependencies]
serde_with = { version = "3.16.1", features = ["json"] }

versionだけでなくfeatures = ["json"] も追加

Struct側に追記

use serde::Deserialize;
use serde_with::{serde_as, json::JsonString};

#[serde_as]
#[derive(Debug, Deserialize)]
pub struct Hoge {
    pub id: String,
    pub name: String,
    #[serde_as(as = "JsonString")]  // 追加
    pub details: HogeDetails,
}

#[derive(Debug, Deserialize)]
pub struct HogeDetails {
    pub key: String,
    pub description: String,
}

#[serde_as] をStructの先頭に、対象フィールドに #[serde_as(as = "JsonString")] を付けて誘導すればよい
serde_with#[serde_as(as = "...")] は、フィールドごとにDeserialize方針を切り替えられるよう
他にもいろいろあるらしいが割愛

おわり

DB側を素直にMapに設計したほうがいいとおもいました
(空でソースを書いているので間違ってたらすみません)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?