【问题标题】:Serde deserialization of partial structs with actix_web使用 actix_web 对部分结构进行 Serde 反序列化
【发布时间】:2020-03-28 00:42:56
【问题描述】:

我有一个 API 端点,它利用 actix_web 反序列化传入的 JSON 有效负载(actix_web 最终使用 serde 进行 JSON 反序列化)。

例如,我有这样的东西:

pub struct IncomingPayload {
    pub field1: i32,
    pub field2: String
}

pub async fn update_platforms(
    pool: web::Data<Pool>,
    req: web::Json<Vec<IncomingPayload>>,
) -> Result<HttpResponse, error::Error> { 
    println!(req.field1); // will be an i32
    println!(req.field2); // will be a String
}

目前,只有serde 能够反序列化结构的所有字段,此端点才会成功返回。 IE。请求必须包含 field1field2 键。

例如这将是成功的:

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"field1": 1,"field2":"something"}' \
  http://localhost:8080

但这不会(因为负载中缺少field2):

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"field1": 1}' \
  http://localhost:8080

所以我的问题是,这可以做到吗?是否可以将带有键值字段子集的 JSON 有效负载发送到期望所有字段都存在的 actix_web 端点?

或者更确切地说,有没有一种通用的方法可以用actix_webserde 反序列化像这样的部分结构?

【问题讨论】:

    标签: json rust serde rust-actix actix-web


    【解决方案1】:

    您可以使用Option&lt;T&gt; 作为字段的类型,使其成为可选字段。如果反序列化过程中缺少某个字段,则该字段设置为None,否则设置为Some(value)

    #[derive(Deserialize)]
    struct IncomingPayload {
        pub field1: Option<i32>,
        pub field2: Option<String>,
    }
    

    对于实现Default的类型,如果字段缺失,也可以使用#[serde(default)]将该字段设置为默认值。

    #[derive(Deserialize)]
    struct IncomingPayload {
        #[serde(default)] // default = 0
        pub field1: i32,
        #[serde(default)] // default = empty string
        pub field2: String,
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-29
      • 1970-01-01
      相关资源
      最近更新 更多